diff --git a/src/Umbraco.Core/Models/ContentEditing/UmbracoEntityTypes.cs b/src/Umbraco.Core/Models/ContentEditing/UmbracoEntityTypes.cs index 7e8cf39ffd..c77500c531 100644 --- a/src/Umbraco.Core/Models/ContentEditing/UmbracoEntityTypes.cs +++ b/src/Umbraco.Core/Models/ContentEditing/UmbracoEntityTypes.cs @@ -1,15 +1,10 @@ -namespace Umbraco.Cms.Core.Models.ContentEditing +namespace Umbraco.Cms.Core.Models.ContentEditing { /// /// Represents the type's of Umbraco entities that can be resolved from the EntityController /// public enum UmbracoEntityTypes { - /// - /// Domain - /// - Domain, - /// /// Language /// @@ -65,6 +60,16 @@ /// Stylesheet, + /// + /// Script + /// + Script, + + /// + /// Partial View + /// + PartialView, + /// /// Member /// diff --git a/src/Umbraco.Core/Models/Mapping/CodeFileMapDefinition.cs b/src/Umbraco.Core/Models/Mapping/CodeFileMapDefinition.cs index d2fd28f510..b185bb586e 100644 --- a/src/Umbraco.Core/Models/Mapping/CodeFileMapDefinition.cs +++ b/src/Umbraco.Core/Models/Mapping/CodeFileMapDefinition.cs @@ -1,4 +1,4 @@ -using Umbraco.Cms.Core.Mapping; +using Umbraco.Cms.Core.Mapping; using Umbraco.Cms.Core.Models.ContentEditing; namespace Umbraco.Cms.Core.Models.Mapping @@ -8,9 +8,14 @@ namespace Umbraco.Cms.Core.Models.Mapping public void DefineMaps(IUmbracoMapper mapper) { mapper.Define((source, context) => new EntityBasic(), Map); - mapper.Define((source, context) => new CodeFileDisplay(), Map); - mapper.Define((source, context) => new CodeFileDisplay(), Map); mapper.Define((source, context) => new CodeFileDisplay(), Map); + + mapper.Define((source, context) => new EntityBasic(), Map); + mapper.Define((source, context) => new CodeFileDisplay(), Map); + + mapper.Define((source, context) => new EntityBasic(), Map); + mapper.Define((source, context) => new CodeFileDisplay(), Map); + mapper.Define(Map); mapper.Define(Map); @@ -27,6 +32,28 @@ namespace Umbraco.Cms.Core.Models.Mapping target.Path = source.Path; } + // Umbraco.Code.MapAll -Trashed -Udi -Icon + private static void Map(IScript source, EntityBasic target, MapperContext context) + { + target.Alias = source.Alias; + target.Id = source.Id; + target.Key = source.Key; + target.Name = source.Name; + target.ParentId = -1; + target.Path = source.Path; + } + + // Umbraco.Code.MapAll -Trashed -Udi -Icon + private static void Map(IPartialView source, EntityBasic target, MapperContext context) + { + target.Alias = source.Alias; + target.Id = source.Id; + target.Key = source.Key; + target.Name = source.Name; + target.ParentId = -1; + target.Path = source.Path; + } + // Umbraco.Code.MapAll -FileType -Notifications -Path -Snippet private static void Map(IPartialView source, CodeFileDisplay target, MapperContext context) { diff --git a/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs b/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs index e3596a268e..6e963bd2da 100644 --- a/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs +++ b/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs @@ -17,6 +17,8 @@ namespace Umbraco.Cms.Core.Models.Packaging public IEnumerable MacroPartialViews { get; set; } // TODO: make strongly typed public IEnumerable Templates { get; set; } // TODO: make strongly typed public IEnumerable Stylesheets { get; set; } // TODO: make strongly typed + public IEnumerable Scripts { get; set; } // TODO: make strongly typed + public IEnumerable PartialViews { get; set; } // TODO: make strongly typed public IEnumerable DataTypes { get; set; } // TODO: make strongly typed public IEnumerable Languages { get; set; } // TODO: make strongly typed public IEnumerable DictionaryItems { get; set; } // TODO: make strongly typed diff --git a/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs b/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs index f4ee9738ab..2b6b3b9e1c 100644 --- a/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs +++ b/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs @@ -38,9 +38,11 @@ namespace Umbraco.Cms.Core.Packaging PackageFile = null, Name = package.Element("name")?.Value, Macros = xml.Root.Element("Macros")?.Elements("macro") ?? Enumerable.Empty(), - MacroPartialViews = xml.Root.Element("MacroPartialViews")?.Elements("view") ?? Enumerable.Empty(), + MacroPartialViews = xml.Root.Element("MacroPartialViews")?.Elements("View") ?? Enumerable.Empty(), + PartialViews = xml.Root.Element("PartialViews")?.Elements("View") ?? Enumerable.Empty(), Templates = xml.Root.Element("Templates")?.Elements("Template") ?? Enumerable.Empty(), - Stylesheets = xml.Root.Element("Stylesheets")?.Elements("styleSheet") ?? Enumerable.Empty(), + Stylesheets = xml.Root.Element("Stylesheets")?.Elements("Stylesheet") ?? Enumerable.Empty(), + Scripts = xml.Root.Element("Scripts")?.Elements("Script") ?? Enumerable.Empty(), DataTypes = xml.Root.Element("DataTypes")?.Elements("DataType") ?? Enumerable.Empty(), Languages = xml.Root.Element("Languages")?.Elements("Language") ?? Enumerable.Empty(), DictionaryItems = xml.Root.Element("DictionaryItems")?.Elements("DictionaryItem") ?? Enumerable.Empty(), diff --git a/src/Umbraco.Core/Packaging/ConflictingPackageData.cs b/src/Umbraco.Core/Packaging/ConflictingPackageData.cs index 27e96d8c82..0d71b9f70e 100644 --- a/src/Umbraco.Core/Packaging/ConflictingPackageData.cs +++ b/src/Umbraco.Core/Packaging/ConflictingPackageData.cs @@ -27,7 +27,7 @@ namespace Umbraco.Cms.Core.Packaging if (xElement == null) throw new FormatException("Missing \"Name\" element"); - return _fileService.GetStylesheetByName(xElement.Value) as IFile; + return _fileService.GetStylesheet(xElement.Value) as IFile; }) .Where(v => v != null); } diff --git a/src/Umbraco.Core/Packaging/InstallationSummary.cs b/src/Umbraco.Core/Packaging/InstallationSummary.cs index 3c519a4a4c..005d5859fb 100644 --- a/src/Umbraco.Core/Packaging/InstallationSummary.cs +++ b/src/Umbraco.Core/Packaging/InstallationSummary.cs @@ -27,6 +27,8 @@ namespace Umbraco.Cms.Core.Packaging public IEnumerable DocumentTypesInstalled { get; set; } = Enumerable.Empty(); public IEnumerable MediaTypesInstalled { get; set; } = Enumerable.Empty(); public IEnumerable StylesheetsInstalled { get; set; } = Enumerable.Empty(); + public IEnumerable ScriptsInstalled { get; set; } = Enumerable.Empty(); + public IEnumerable PartialViewsInstalled { get; set; } = Enumerable.Empty(); public IEnumerable ContentInstalled { get; set; } = Enumerable.Empty(); public IEnumerable MediaInstalled { get; set; } = Enumerable.Empty(); public string PackageName { get; } diff --git a/src/Umbraco.Core/Packaging/PackageDefinition.cs b/src/Umbraco.Core/Packaging/PackageDefinition.cs index 3c808d4de0..345d669b15 100644 --- a/src/Umbraco.Core/Packaging/PackageDefinition.cs +++ b/src/Umbraco.Core/Packaging/PackageDefinition.cs @@ -52,6 +52,9 @@ namespace Umbraco.Cms.Core.Packaging [DataMember(Name = "templates")] public IList Templates { get; set; } = new List(); + [DataMember(Name = "partialViews")] + public IList PartialViews { get; set; } = new List(); + [DataMember(Name = "documentTypes")] public IList DocumentTypes { get; set; } = new List(); @@ -61,6 +64,9 @@ namespace Umbraco.Cms.Core.Packaging [DataMember(Name = "stylesheets")] public IList Stylesheets { get; set; } = new List(); + [DataMember(Name = "scripts")] + public IList Scripts { get; set; } = new List(); + [DataMember(Name = "dataTypes")] public IList DataTypes { get; set; } = new List(); diff --git a/src/Umbraco.Core/Packaging/PackageDefinitionXmlParser.cs b/src/Umbraco.Core/Packaging/PackageDefinitionXmlParser.cs index 69c109aee4..7cca061401 100644 --- a/src/Umbraco.Core/Packaging/PackageDefinitionXmlParser.cs +++ b/src/Umbraco.Core/Packaging/PackageDefinitionXmlParser.cs @@ -12,6 +12,10 @@ namespace Umbraco.Cms.Core.Packaging /// public class PackageDefinitionXmlParser { + private static readonly IList s_emptyStringList = new List(); + private static readonly IList s_emptyGuidUdiList = new List(); + + public PackageDefinition ToPackageDefinition(XElement xml) { if (xml == null) @@ -27,16 +31,18 @@ namespace Umbraco.Cms.Core.Packaging PackageId = xml.AttributeValue("packageGuid"), ContentNodeId = xml.Element("content")?.AttributeValue("nodeId") ?? string.Empty, ContentLoadChildNodes = xml.Element("content")?.AttributeValue("loadChildNodes") ?? false, - MediaUdis = xml.Element("media")?.Elements("nodeUdi").Select(x => (GuidUdi)UdiParser.Parse(x.Value)).ToList() ?? new List(), + MediaUdis = xml.Element("media")?.Elements("nodeUdi").Select(x => (GuidUdi)UdiParser.Parse(x.Value)).ToList() ?? s_emptyGuidUdiList, MediaLoadChildNodes = xml.Element("media")?.AttributeValue("loadChildNodes") ?? false, - Macros = xml.Element("macros")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), - Templates = xml.Element("templates")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), - Stylesheets = xml.Element("stylesheets")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), - DocumentTypes = xml.Element("documentTypes")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), - MediaTypes = xml.Element("mediaTypes")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), - Languages = xml.Element("languages")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), - DictionaryItems = xml.Element("dictionaryitems")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), - DataTypes = xml.Element("datatypes")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), + Macros = xml.Element("macros")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? s_emptyStringList, + Templates = xml.Element("templates")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? s_emptyStringList, + Stylesheets = xml.Element("stylesheets")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? s_emptyStringList, + Scripts = xml.Element("scripts")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? s_emptyStringList, + PartialViews = xml.Element("partialViews")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? s_emptyStringList, + DocumentTypes = xml.Element("documentTypes")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? s_emptyStringList, + MediaTypes = xml.Element("mediaTypes")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? s_emptyStringList, + Languages = xml.Element("languages")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? s_emptyStringList, + DictionaryItems = xml.Element("dictionaryitems")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? s_emptyStringList, + DataTypes = xml.Element("datatypes")?.Value.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries).ToList() ?? s_emptyStringList, }; return retVal; @@ -57,6 +63,8 @@ namespace Umbraco.Cms.Core.Packaging new XElement("templates", string.Join(",", def.Templates ?? Array.Empty())), new XElement("stylesheets", string.Join(",", def.Stylesheets ?? Array.Empty())), + new XElement("scripts", string.Join(",", def.Scripts ?? Array.Empty())), + new XElement("partialViews", string.Join(",", def.PartialViews ?? Array.Empty())), new XElement("documentTypes", string.Join(",", def.DocumentTypes ?? Array.Empty())), new XElement("mediaTypes", string.Join(",", def.MediaTypes ?? Array.Empty())), new XElement("macros", string.Join(",", def.Macros ?? Array.Empty())), diff --git a/src/Umbraco.Core/Packaging/PackagesRepository.cs b/src/Umbraco.Core/Packaging/PackagesRepository.cs index f8e651c7fa..ffc67663cc 100644 --- a/src/Umbraco.Core/Packaging/PackagesRepository.cs +++ b/src/Umbraco.Core/Packaging/PackagesRepository.cs @@ -6,9 +6,7 @@ using System.IO.Compression; using System.Linq; using System.Text; using System.Xml.Linq; -using System.Xml.XPath; using Microsoft.Extensions.Options; -using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Hosting; using Umbraco.Cms.Core.IO; @@ -40,6 +38,7 @@ namespace Umbraco.Cms.Core.Packaging private readonly IMediaService _mediaService; private readonly IMediaTypeService _mediaTypeService; private readonly MediaFileManager _mediaFileManager; + private readonly FileSystems _fileSystems; /// /// Constructor @@ -72,6 +71,7 @@ namespace Umbraco.Cms.Core.Packaging IMediaService mediaService, IMediaTypeService mediaTypeService, MediaFileManager mediaFileManager, + FileSystems fileSystems, string packageRepositoryFileName, string tempFolderPath = null, string packagesFolderPath = null, @@ -97,6 +97,7 @@ namespace Umbraco.Cms.Core.Packaging _mediaService = mediaService; _mediaTypeService = mediaTypeService; _mediaFileManager = mediaFileManager; + _fileSystems = fileSystems; } private string CreatedPackagesFile => _packagesFolderPath.EnsureEndsWith('/') + _packageRepositoryFileName; @@ -190,7 +191,7 @@ namespace Umbraco.Cms.Core.Packaging try { //Init package file - var compiledPackageXml = CreateCompiledPackageXml(out var root); + XDocument compiledPackageXml = CreateCompiledPackageXml(out XElement root); //Info section root.Add(GetPackageInfoXml(definition)); @@ -200,6 +201,8 @@ namespace Umbraco.Cms.Core.Packaging PackageMediaTypes(definition, root); PackageTemplates(definition, root); PackageStylesheets(definition, root); + PackageStaticFiles(definition.Scripts, root, "Scripts", "Script", _fileSystems.ScriptsFileSystem); + PackageStaticFiles(definition.PartialViews, root, "PartialViews", "View", _fileSystems.PartialViewsFileSystem); PackageMacros(definition, root); PackageDictionaryItems(definition, root); PackageLanguages(definition, root); @@ -396,23 +399,62 @@ namespace Umbraco.Cms.Core.Packaging // get the partial views for macros and package those IEnumerable views = packagedMacros.Select(x => x.MacroSource).Where(x => x.EndsWith(".cshtml")); - PackagePartialViews(views, root, "MacroPartialViews"); + PackageMacroPartialViews(views, root); } private void PackageStylesheets(PackageDefinition definition, XContainer root) { var stylesheetsXml = new XElement("Stylesheets"); - foreach (var stylesheetName in definition.Stylesheets) + foreach (var stylesheet in definition.Stylesheets) { - if (stylesheetName.IsNullOrWhiteSpace()) + if (stylesheet.IsNullOrWhiteSpace()) + { continue; - var xml = GetStylesheetXml(stylesheetName, true); + } + + XElement xml = GetStylesheetXml(stylesheet, true); if (xml != null) + { stylesheetsXml.Add(xml); + } } root.Add(stylesheetsXml); } + private void PackageStaticFiles( + IEnumerable filePaths, + XContainer root, + string containerName, + string elementName, + IFileSystem fileSystem) + { + var scriptsXml = new XElement(containerName); + foreach (var file in filePaths) + { + if (file.IsNullOrWhiteSpace()) + { + continue; + } + + if (!fileSystem.FileExists(file)) + { + throw new InvalidOperationException("No file found with path " + file); + } + + using (Stream stream = fileSystem.OpenFile(file)) + using (var reader = new StreamReader(stream)) + { + var fileContents = reader.ReadToEnd(); + scriptsXml.Add( + new XElement( + elementName, + new XAttribute("path", file), + new XCData(fileContents))); + } + } + root.Add(scriptsXml); + } + private void PackageTemplates(PackageDefinition definition, XContainer root) { var templatesXml = new XElement("Templates"); @@ -428,9 +470,9 @@ namespace Umbraco.Cms.Core.Packaging root.Add(templatesXml); } - private void PackagePartialViews(IEnumerable viewPaths, XContainer root, string elementName) + private void PackageMacroPartialViews(IEnumerable viewPaths, XContainer root) { - var viewsXml = new XElement(elementName); + var viewsXml = new XElement("MacroPartialViews"); foreach (var viewPath in viewPaths) { // TODO: See TODO note in MacrosController about the inconsistencies of usages of partial views @@ -447,7 +489,7 @@ namespace Umbraco.Cms.Core.Packaging viewsXml.Add( new XElement( - "view", + "View", new XAttribute("path", viewPath), new XCData(fileContents))); } @@ -631,34 +673,23 @@ namespace Umbraco.Cms.Core.Packaging /// /// Converts a umbraco stylesheet to a package xml node /// - /// The name of the stylesheet. + /// The path of the stylesheet. /// if set to true [include properties]. /// - private XElement GetStylesheetXml(string name, bool includeProperties) + private XElement GetStylesheetXml(string path, bool includeProperties) { - if (string.IsNullOrWhiteSpace(name)) - throw new ArgumentException("Value cannot be null or whitespace.", nameof(name)); - var sts = _fileService.GetStylesheetByName(name); - if (sts == null) - return null; - var stylesheetXml = new XElement("Stylesheet"); - stylesheetXml.Add(new XElement("Name", sts.Alias)); - stylesheetXml.Add(new XElement("FileName", sts.Name)); - stylesheetXml.Add(new XElement("Content", new XCData(sts.Content))); - - if (!includeProperties) - return stylesheetXml; - - var properties = new XElement("Properties"); - foreach (var ssP in sts.Properties) + if (string.IsNullOrWhiteSpace(path)) { - var property = new XElement("Property"); - property.Add(new XElement("Name", ssP.Name)); - property.Add(new XElement("Alias", ssP.Alias)); - property.Add(new XElement("Value", ssP.Value)); + throw new ArgumentException("Value cannot be null or whitespace.", nameof(path)); } - stylesheetXml.Add(properties); - return stylesheetXml; + + IStylesheet stylesheet = _fileService.GetStylesheet(path); + if (stylesheet == null) + { + return null; + } + + return _serializer.Serialize(stylesheet, includeProperties); } private void AddDocumentType(IContentType dt, HashSet dtl) diff --git a/src/Umbraco.Core/Services/IEntityXmlSerializer.cs b/src/Umbraco.Core/Services/IEntityXmlSerializer.cs index 97838b1a69..c3e8a29e8e 100644 --- a/src/Umbraco.Core/Services/IEntityXmlSerializer.cs +++ b/src/Umbraco.Core/Services/IEntityXmlSerializer.cs @@ -56,7 +56,7 @@ namespace Umbraco.Cms.Core.Services /// containing the xml representation of the IDictionaryItem object XElement Serialize(IDictionaryItem dictionaryItem, bool includeChildren); - XElement Serialize(Stylesheet stylesheet); + XElement Serialize(IStylesheet stylesheet, bool includeProperties); /// /// Exports a list of items to xml as an diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs index 5df5602bc6..903603c415 100644 --- a/src/Umbraco.Core/Services/IFileService.cs +++ b/src/Umbraco.Core/Services/IFileService.cs @@ -15,6 +15,13 @@ namespace Umbraco.Cms.Core.Services void CreatePartialViewMacroFolder(string folderPath); void DeletePartialViewFolder(string folderPath); void DeletePartialViewMacroFolder(string folderPath); + + /// + /// Gets a list of all objects + /// + /// An enumerable list of objects + IEnumerable GetPartialViews(params string[] names); + IPartialView GetPartialView(string path); IPartialView GetPartialViewMacro(string path); Attempt CreatePartialView(IPartialView partialView, string snippetName = null, int userId = Constants.Security.SuperUserId); @@ -77,7 +84,7 @@ namespace Umbraco.Cms.Core.Services /// /// Name of the stylesheet incl. extension /// A object - IStylesheet GetStylesheetByName(string name); + IStylesheet GetStylesheet(string name); /// /// Saves a @@ -127,12 +134,18 @@ namespace Umbraco.Cms.Core.Services /// The size of the stylesheet. long GetStylesheetFileSize(string filepath); + /// + /// Gets a list of all objects + /// + /// An enumerable list of objects + IEnumerable GetScripts(params string[] names); + /// /// Gets a object by its name /// /// Name of the script incl. extension /// A object - IScript GetScriptByName(string name); + IScript GetScript(string name); /// /// Saves a diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Services.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Services.cs index 14da8f7aa6..8b34289c9c 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Services.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Services.cs @@ -95,6 +95,7 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), + factory.GetRequiredService(), packageRepoFileName); private static LocalizedTextServiceFileSources SourcesFactory(IServiceProvider container) diff --git a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs index 8d87570229..91e3829806 100644 --- a/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs +++ b/src/Umbraco.Infrastructure/Packaging/PackageDataInstallation.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Net; using System.Text; @@ -106,6 +107,8 @@ namespace Umbraco.Cms.Infrastructure.Packaging var importedMediaTypes = installationSummary.MediaTypesInstalled.ToDictionary(x => x.Alias, x => x); installationSummary.StylesheetsInstalled = ImportStylesheets(compiledPackage.Stylesheets, userId); + installationSummary.PartialViewsInstalled = ImportPartialViews(compiledPackage.PartialViews, userId); + installationSummary.ScriptsInstalled = ImportScripts(compiledPackage.Scripts, userId); installationSummary.ContentInstalled = ImportContentBase(compiledPackage.Documents, importedDocTypes, userId, _contentTypeService, _contentService); installationSummary.MediaInstalled = ImportContentBase(compiledPackage.Media, importedMediaTypes, userId, _mediaTypeService, _mediaService); @@ -1239,30 +1242,6 @@ namespace Umbraco.Cms.Infrastructure.Packaging #endregion - private void ImportPartialViews(IEnumerable viewElements) - { - foreach(XElement element in viewElements) - { - var path = element.AttributeValue("path"); - if (path == null) - { - throw new InvalidOperationException("No path attribute found"); - } - var contents = element.Value; - if (contents.IsNullOrWhiteSpace()) - { - throw new InvalidOperationException("No content found for partial view"); - } - - var physicalPath = _hostingEnvironment.MapPathContentRoot(path); - // TODO: Do we overwrite? IMO I don't think so since these will be views a user will change. - if (!System.IO.File.Exists(physicalPath)) - { - System.IO.File.WriteAllText(physicalPath, contents, Encoding.UTF8); - } - } - } - #region Macros /// @@ -1283,11 +1262,35 @@ namespace Umbraco.Cms.Infrastructure.Packaging _macroService.Save(macro, userId); } - ImportPartialViews(macroPartialViewsElements); + ImportMacroPartialViews(macroPartialViewsElements); return macros; } + private void ImportMacroPartialViews(IEnumerable viewElements) + { + foreach (XElement element in viewElements) + { + var path = element.AttributeValue("path"); + if (path == null) + { + throw new InvalidOperationException("No path attribute found"); + } + var contents = element.Value; + if (contents.IsNullOrWhiteSpace()) + { + throw new InvalidOperationException("No content found for partial view"); + } + + var physicalPath = _hostingEnvironment.MapPathContentRoot(path); + // TODO: Do we overwrite? IMO I don't think so since these will be views a user will change. + if (!System.IO.File.Exists(physicalPath)) + { + System.IO.File.WriteAllText(physicalPath, contents, Encoding.UTF8); + } + } + } + private IMacro ParseMacroElement(XElement macroElement) { var macroKey = Guid.Parse(macroElement.Element("key").Value); @@ -1368,30 +1371,98 @@ namespace Umbraco.Cms.Infrastructure.Packaging #endregion + public IReadOnlyList ImportScripts(IEnumerable scriptElements, int userId) + { + var result = new List(); + + foreach (XElement scriptXml in scriptElements) + { + var path = scriptXml.AttributeValue("path"); + + if (path.IsNullOrWhiteSpace()) + { + continue; + } + + IScript script = _fileService.GetScript(path); + + // only update if it doesn't exist + if (script == null) + { + var content = scriptXml.Value; + if (content == null) + { + continue; + } + + script = new Script(path) { Content = content }; + _fileService.SaveScript(script, userId); + result.Add(script); + } + } + + return result; + } + + public IReadOnlyList ImportPartialViews(IEnumerable partialViewElements, int userId) + { + var result = new List(); + + foreach (XElement partialViewXml in partialViewElements) + { + var path = partialViewXml.AttributeValue("path"); + + if (path.IsNullOrWhiteSpace()) + { + continue; + } + + IPartialView partialView = _fileService.GetPartialView(path); + + // only update if it doesn't exist + if (partialView == null) + { + var content = partialViewXml.Value; + if (content == null) + { + continue; + } + + partialView = new PartialView(PartialViewType.PartialView, path) { Content = content }; + _fileService.SavePartialView(partialView, userId); + result.Add(partialView); + } + } + + return result; + } + #region Stylesheets public IReadOnlyList ImportStylesheets(IEnumerable stylesheetElements, int userId) { var result = new List(); - foreach (var n in stylesheetElements) + foreach (XElement n in stylesheetElements) { - var stylesheetName = n.Element("Name")?.Value; - if (stylesheetName.IsNullOrWhiteSpace()) - continue; + var stylesheetPath = n.Element("FileName")?.Value; - var s = _fileService.GetStylesheetByName(stylesheetName); + if (stylesheetPath.IsNullOrWhiteSpace()) + { + continue; + } + + IStylesheet s = _fileService.GetStylesheet(stylesheetPath); if (s == null) { - var fileName = n.Element("FileName")?.Value; - if (fileName == null) - continue; var content = n.Element("Content")?.Value; if (content == null) + { continue; + } - s = new Stylesheet(fileName) { Content = content }; - _fileService.SaveStylesheet(s); + s = new Stylesheet(stylesheetPath) { Content = content }; + _fileService.SaveStylesheet(s, userId); } foreach (var prop in n.XPathSelectElements("Properties/Property")) @@ -1419,7 +1490,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging sp.Alias = alias; sp.Value = prop.Element("Value")?.Value; } - _fileService.SaveStylesheet(s); + _fileService.SaveStylesheet(s, userId); result.Add(s); } diff --git a/src/Umbraco.Infrastructure/Services/Implement/EntityXmlSerializer.cs b/src/Umbraco.Infrastructure/Services/Implement/EntityXmlSerializer.cs index 2e46b0b975..11fbd87232 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/EntityXmlSerializer.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/EntityXmlSerializer.cs @@ -264,13 +264,18 @@ namespace Umbraco.Cms.Core.Services.Implement return xml; } - public XElement Serialize(Stylesheet stylesheet) + public XElement Serialize(IStylesheet stylesheet, bool includeProperties) { var xml = new XElement("Stylesheet", new XElement("Name", stylesheet.Alias), new XElement("FileName", stylesheet.Path), new XElement("Content", new XCData(stylesheet.Content))); + if (!includeProperties) + { + return xml; + } + var props = new XElement("Properties"); xml.Add(props); diff --git a/src/Umbraco.Infrastructure/Services/Implement/FileService.cs b/src/Umbraco.Infrastructure/Services/Implement/FileService.cs index 6d7d5b4490..64ae7c5dfc 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/FileService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/FileService.cs @@ -65,11 +65,11 @@ namespace Umbraco.Cms.Core.Services.Implement } /// - public IStylesheet GetStylesheetByName(string name) + public IStylesheet GetStylesheet(string path) { using (IScope scope = ScopeProvider.CreateScope(autoComplete: true)) { - return _stylesheetRepository.Get(name); + return _stylesheetRepository.Get(path); } } @@ -177,7 +177,16 @@ namespace Umbraco.Cms.Core.Services.Implement #region Scripts /// - public IScript GetScriptByName(string name) + public IEnumerable GetScripts(params string[] names) + { + using (IScope scope = ScopeProvider.CreateScope(autoComplete: true)) + { + return _scriptRepository.GetMany(names); + } + } + + /// + public IScript GetScript(string name) { using (IScope scope = ScopeProvider.CreateScope(autoComplete: true)) { @@ -647,6 +656,14 @@ namespace Umbraco.Cms.Core.Services.Implement } } + public IEnumerable GetPartialViews(params string[] names) + { + using (IScope scope = ScopeProvider.CreateScope(autoComplete: true)) + { + return _partialViewRepository.GetMany(names); + } + } + public IPartialView GetPartialView(string path) { using (IScope scope = ScopeProvider.CreateScope(autoComplete: true)) diff --git a/src/Umbraco.Tests.Integration/Umbraco.Core/Packaging/CreatedPackagesRepositoryTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Core/Packaging/CreatedPackagesRepositoryTests.cs index 892c7595d5..ca0b3dc9e4 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Core/Packaging/CreatedPackagesRepositoryTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Core/Packaging/CreatedPackagesRepositoryTests.cs @@ -59,6 +59,8 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Packaging private MediaFileManager MediaFileManager => GetRequiredService(); + private FileSystems FileSystems => GetRequiredService(); + public ICreatedPackagesRepository PackageBuilder => new PackagesRepository( ContentService, ContentTypeService, @@ -72,6 +74,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Packaging MediaService, MediaTypeService, MediaFileManager, + FileSystems, "createdPackages.config", // temp paths diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Packaging/PackageDataInstallationTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Packaging/PackageDataInstallationTests.cs index cd2f438c14..1c094b97f0 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Packaging/PackageDataInstallationTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Packaging/PackageDataInstallationTests.cs @@ -648,7 +648,10 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Packaging XElement macrosElement = xml.Descendants("Macros").First(); // Act - var macros = PackageDataInstallation.ImportMacros(macrosElement.Elements("macro"), 0).ToList(); + var macros = PackageDataInstallation.ImportMacros( + macrosElement.Elements("macro"), + Enumerable.Empty(), + 0).ToList(); // Assert Assert.That(macros.Any(), Is.True); @@ -669,7 +672,10 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Packaging XElement macrosElement = xml.Descendants("Macros").First(); // Act - var macros = PackageDataInstallation.ImportMacros(macrosElement.Elements("macro"), 0).ToList(); + var macros = PackageDataInstallation.ImportMacros( + macrosElement.Elements("macro"), + Enumerable.Empty(), + 0).ToList(); // Assert Assert.That(macros.Any(), Is.True); diff --git a/src/Umbraco.Web.BackOffice/Controllers/CodeFileController.cs b/src/Umbraco.Web.BackOffice/Controllers/CodeFileController.cs index a88cdc5087..64a47c4cc4 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/CodeFileController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/CodeFileController.cs @@ -213,7 +213,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers } break; case Constants.Trees.Scripts: - var script = _fileService.GetScriptByName(virtualPath); + var script = _fileService.GetScript(virtualPath); if (script != null) { var display = _umbracoMapper.Map(script); @@ -224,7 +224,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers } break; case Constants.Trees.Stylesheets: - var stylesheet = _fileService.GetStylesheetByName(virtualPath); + var stylesheet = _fileService.GetStylesheet(virtualPath); if (stylesheet != null) { var display = _umbracoMapper.Map(stylesheet); @@ -371,7 +371,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers _fileService.DeleteScriptFolder(virtualPath); return Ok(); } - if (_fileService.GetScriptByName(virtualPath) != null) + if (_fileService.GetScript(virtualPath) != null) { _fileService.DeleteScript(virtualPath, currentUser.Id); return Ok(); @@ -383,7 +383,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers _fileService.DeleteStyleSheetFolder(virtualPath); return Ok(); } - if (_fileService.GetStylesheetByName(virtualPath) != null) + if (_fileService.GetStylesheet(virtualPath) != null) { _fileService.DeleteStylesheet(virtualPath, currentUser.Id); return Ok(); @@ -540,7 +540,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers private IScript CreateOrUpdateScript(CodeFileDisplay display) { return CreateOrUpdateFile(display, ".js", _fileSystems.ScriptsFileSystem, - name => _fileService.GetScriptByName(name), + name => _fileService.GetScript(name), (script, userId) => _fileService.SaveScript(script, userId), name => new Script(name)); } @@ -548,7 +548,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers private IStylesheet CreateOrUpdateStylesheet(CodeFileDisplay display) { return CreateOrUpdateFile(display, ".css", _fileSystems.StylesheetsFileSystem, - name => _fileService.GetStylesheetByName(name), + name => _fileService.GetStylesheet(name), (stylesheet, userId) => _fileService.SaveStylesheet(stylesheet, userId), name => new Stylesheet(name) ); diff --git a/src/Umbraco.Web.BackOffice/Controllers/EntityController.cs b/src/Umbraco.Web.BackOffice/Controllers/EntityController.cs index 6924780cd2..fdfdb90210 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/EntityController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/EntityController.cs @@ -545,7 +545,6 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers //now we need to convert the unknown ones switch (type) { - case UmbracoEntityTypes.Domain: case UmbracoEntityTypes.Language: case UmbracoEntityTypes.User: case UmbracoEntityTypes.Macro: @@ -705,7 +704,6 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers { case UmbracoEntityTypes.PropertyType: case UmbracoEntityTypes.PropertyGroup: - case UmbracoEntityTypes.Domain: case UmbracoEntityTypes.Language: case UmbracoEntityTypes.User: case UmbracoEntityTypes.Macro: @@ -791,7 +789,6 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers { case UmbracoEntityTypes.PropertyType: case UmbracoEntityTypes.PropertyGroup: - case UmbracoEntityTypes.Domain: case UmbracoEntityTypes.Language: case UmbracoEntityTypes.User: case UmbracoEntityTypes.Macro: @@ -835,7 +832,6 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers //now we need to convert the unknown ones switch (entityType) { - case UmbracoEntityTypes.Domain: case UmbracoEntityTypes.Language: case UmbracoEntityTypes.User: case UmbracoEntityTypes.Macro: @@ -902,7 +898,6 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers { case UmbracoEntityTypes.PropertyType: case UmbracoEntityTypes.PropertyGroup: - case UmbracoEntityTypes.Domain: case UmbracoEntityTypes.Language: case UmbracoEntityTypes.User: case UmbracoEntityTypes.Macro: @@ -934,7 +929,6 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers { case UmbracoEntityTypes.PropertyType: case UmbracoEntityTypes.PropertyGroup: - case UmbracoEntityTypes.Domain: case UmbracoEntityTypes.Language: case UmbracoEntityTypes.User: case UmbracoEntityTypes.Macro: @@ -966,7 +960,6 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers { case UmbracoEntityTypes.PropertyType: case UmbracoEntityTypes.PropertyGroup: - case UmbracoEntityTypes.Domain: case UmbracoEntityTypes.Language: case UmbracoEntityTypes.User: case UmbracoEntityTypes.Macro: @@ -994,8 +987,6 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers case UmbracoEntityTypes.PropertyGroup: - case UmbracoEntityTypes.Domain: - case UmbracoEntityTypes.Language: case UmbracoEntityTypes.User: @@ -1026,8 +1017,6 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers case UmbracoEntityTypes.PropertyGroup: - case UmbracoEntityTypes.Domain: - case UmbracoEntityTypes.Language: case UmbracoEntityTypes.User: @@ -1140,6 +1129,20 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers return _fileService.GetStylesheets().Select(MapEntities()); + case UmbracoEntityTypes.Script: + + if (!postFilter.IsNullOrWhiteSpace()) + throw new NotSupportedException("Filtering on scripts is not currently supported"); + + return _fileService.GetScripts().Select(MapEntities()); + + case UmbracoEntityTypes.PartialView: + + if (!postFilter.IsNullOrWhiteSpace()) + throw new NotSupportedException("Filtering on scripts is not currently supported"); + + return _fileService.GetPartialViews().Select(MapEntities()); + case UmbracoEntityTypes.Language: if (!postFilter.IsNullOrWhiteSpace()) @@ -1153,7 +1156,6 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers return GetAllDictionaryItems(); - case UmbracoEntityTypes.Domain: default: throw new NotSupportedException("The " + typeof(EntityController) + " does not currently support data for the type " + entityType); } diff --git a/src/Umbraco.Web.BackOffice/Controllers/PackageController.cs b/src/Umbraco.Web.BackOffice/Controllers/PackageController.cs index b9cac44c04..dca3a320ec 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/PackageController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/PackageController.cs @@ -75,10 +75,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers return package; } - public PackageDefinition GetEmpty() - { - return new PackageDefinition(); - } + public PackageDefinition GetEmpty() => new PackageDefinition(); /// /// Creates or updates a package diff --git a/src/Umbraco.Web.BackOffice/Controllers/StylesheetController.cs b/src/Umbraco.Web.BackOffice/Controllers/StylesheetController.cs index 0eb18cf7cd..4f64a34632 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/StylesheetController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/StylesheetController.cs @@ -33,7 +33,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers public IEnumerable GetRulesByName(string name) { - var css = _fileService.GetStylesheetByName(name.EnsureEndsWith(".css")); + var css = _fileService.GetStylesheet(name.EnsureEndsWith(".css")); if (css == null) return Enumerable.Empty(); diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js index 2c6c489e22..f5db75ebe1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js @@ -1,401 +1,443 @@ (function () { - "use strict"; + "use strict"; - function EditController($scope, $location, $routeParams, umbRequestHelper, entityResource, packageResource, editorService, formHelper, localizationService) { + function EditController($scope, $location, $routeParams, umbRequestHelper, entityResource, packageResource, editorService, formHelper, localizationService) { - const vm = this; + const vm = this; - const packageId = $routeParams.id; - const create = $routeParams.create; + const packageId = $routeParams.id; + const create = $routeParams.create; - vm.showBackButton = true; + vm.showBackButton = true; - // open all expansion panels - vm.loading = true; - vm.mediaNodeDisplayModels = []; - vm.back = back; - vm.createOrUpdatePackage = createOrUpdatePackage; - vm.removeContentItem = removeContentItem; - vm.openContentPicker = openContentPicker; - vm.openViewPicker = openViewPicker; - vm.removePackageView = removePackageView; - vm.downloadFile = downloadFile; + // open all expansion panels + vm.loading = true; + vm.mediaNodeDisplayModels = []; + vm.back = back; + vm.createOrUpdatePackage = createOrUpdatePackage; + vm.removeContentItem = removeContentItem; + vm.openContentPicker = openContentPicker; + vm.openViewPicker = openViewPicker; + vm.removePackageView = removePackageView; + vm.downloadFile = downloadFile; - vm.selectDocumentType = selectDocumentType; - vm.selectMediaType = selectMediaType; - vm.selectTemplate = selectTemplate; - vm.selectStyleSheet = selectStyleSheet; - vm.selectMacro = selectMacro; - vm.selectLanguage = selectLanguage; - vm.selectDictionaryItem = selectDictionaryItem; - vm.selectDataType = selectDataType; + vm.selectDocumentType = selectDocumentType; + vm.selectMediaType = selectMediaType; + vm.selectTemplate = selectTemplate; + vm.selectStyleSheet = selectStyleSheet; + vm.selectScript = selectScript; + vm.selectPartialView = selectPartialView; + vm.selectMacro = selectMacro; + vm.selectLanguage = selectLanguage; + vm.selectDictionaryItem = selectDictionaryItem; + vm.selectDataType = selectDataType; - vm.mediaPickerModel = { - hideLabel: true, - view: "mediapicker", - value: "", - config: { - multiPicker: true, - allowEdit:false - } - } - vm.labels = {}; - - vm.versionRegex = /^(\d+\.)(\d+\.)(\*|\d+)$/; - - vm.aceOption = { - mode: "xml", - theme: "chrome", - showPrintMargin: false, - advanced: { - fontSize: '14px', - enableSnippets: true, - enableBasicAutocompletion: true, - enableLiveAutocompletion: false - }, - onLoad: function (_editor) { - vm.editor = _editor; - - vm.editor.setValue(vm.package.actions); - } - }; - - function onInit() { - - if (create) { - // Pre populate package with some values - packageResource.getEmpty().then(scaffold => { - vm.package = scaffold; - - loadResources(); - - vm.loading = false; - }); - - localizationService.localizeMany(["general_create", "packager_includeAllChildNodes"]).then(function (values) { - vm.labels.button = values[0]; - vm.labels.includeAllChildNodes = values[1]; - }); - } else { - // Load package - packageResource.getCreatedById(packageId).then(createdPackage => { - vm.package = createdPackage; - - loadResources(); - - vm.loading = false; - - // Get render model for content node - if (vm.package.contentNodeId) { - entityResource.getById(vm.package.contentNodeId, "Document") - .then((entity) => { - vm.contentNodeDisplayModel = entity; - }); - } - - vm.mediaPickerModel.value = vm.package.mediaUdis.join(','); - }); - - - localizationService.localizeMany(["buttons_save", "packager_includeAllChildNodes"]).then(function (values) { - vm.labels.button = values[0]; - vm.labels.includeAllChildNodes = values[1]; - }); - } - } - - function loadResources() { - - // Get all document types - entityResource.getAll("DocumentType").then(documentTypes => { - // a package stores the id as a string so we - // need to convert all ids to string for comparison - documentTypes.forEach(documentType => { - documentType.id = documentType.id.toString(); - documentType.selected = vm.package.documentTypes.indexOf(documentType.id) !== -1; - }); - vm.documentTypes = documentTypes; - }); - - // Get all media types - entityResource.getAll("MediaType").then(mediaTypes => { - // a package stores the id as a string so we - // need to convert all ids to string for comparison - mediaTypes.forEach(mediaType => { - mediaType.id = mediaType.id.toString(); - mediaType.selected = vm.package.mediaTypes.indexOf(mediaType.id) !== -1; - }); - vm.mediaTypes = mediaTypes; - }); - - // Get all templates - entityResource.getAll("Template").then(templates => { - // a package stores the id as a string so we - // need to convert all ids to string for comparison - templates.forEach(template => { - template.id = template.id.toString(); - template.selected = vm.package.templates.indexOf(template.id) >= 0; - }); - vm.templates = templates; - }); - - // Get all stylesheets - entityResource.getAll("Stylesheet").then(stylesheets => { - stylesheets.forEach(stylesheet => { - stylesheet.selected = vm.package.stylesheets.indexOf(stylesheet.name) >= 0; - }); - vm.stylesheets = stylesheets; - }); - - // Get all macros - entityResource.getAll("Macro").then(macros => { - // a package stores the id as a string so we - // need to convert all ids to string for comparison - macros.forEach(macro => { - macro.id = macro.id.toString(); - macro.selected = vm.package.macros.indexOf(macro.id) !== -1; - }); - vm.macros = macros; - }); - - // Get all languages - entityResource.getAll("Language").then(languages => { - // a package stores the id as a string so we - // need to convert all ids to string for comparison - languages.forEach(language => { - language.id = language.id.toString(); - language.selected = vm.package.languages.indexOf(language.id) !== -1; - }); - vm.languages = languages; - }); - - // Get all dictionary items - entityResource.getAll("DictionaryItem").then(dictionaryItems => { - // a package stores the id as a string so we - // need to convert all ids to string for comparison - dictionaryItems.forEach(dictionaryItem => { - dictionaryItem.id = dictionaryItem.id.toString(); - dictionaryItem.selected = vm.package.dictionaryItems.indexOf(dictionaryItem.id) !== -1; - }); - vm.dictionaryItems = dictionaryItems; - }); - - // Get all data types - entityResource.getAll("DataType").then(dataTypes => { - // a package stores the id as a string so we - // need to convert all ids to string for comparison - dataTypes.forEach(dataType => { - dataType.id = dataType.id.toString(); - dataType.selected = vm.package.dataTypes.indexOf(dataType.id) !== -1; - }); - vm.dataTypes = dataTypes; - }); - - } - - function downloadFile(id) { - var url = umbRequestHelper.getApiUrl( - "packageApiBaseUrl", - "DownloadCreatedPackage", - { id: id }); - - umbRequestHelper.downloadFile(url).then(function () { - - }); - } - - function back() { - $location.path("packages/packages/created").search("create", null).search("packageId", null); - } - - function createOrUpdatePackage(editPackageForm) { - - // Split by comma and remove empty entries - vm.package.mediaUdis = vm.mediaPickerModel.value.split(",").filter(i => i); - if (formHelper.submitForm({ formCtrl: editPackageForm, scope: $scope })) { - - vm.buttonState = "busy"; - - packageResource.savePackage(vm.package).then((updatedPackage) => { - - vm.package = updatedPackage; - vm.buttonState = "success"; - - formHelper.resetForm({ scope: $scope, formCtrl: editPackageForm }); - - if (create) { - //if we are creating, then redirect to the correct url and reload - $location.path("packages/packages/edit/" + vm.package.id).search("create", null); - //don't add a browser history for this - $location.replace(); - } - - }, function (err) { - formHelper.resetForm({ scope: $scope, formCtrl: editPackageForm, hasErrors: true }); - formHelper.handleError(err); - vm.buttonState = "error"; - }); - } - } - - function removeContentItem() { - vm.package.contentNodeId = null; - } - - function openContentPicker() { - const contentPicker = { - submit: function (model) { - if (model.selection && model.selection.length > 0) { - vm.package.contentNodeId = model.selection[0].id.toString(); - vm.contentNodeDisplayModel = model.selection[0]; - } - editorService.close(); - }, - close: function () { - editorService.close(); - } - }; - editorService.contentPicker(contentPicker); + vm.mediaPickerModel = { + hideLabel: true, + view: "mediapicker", + value: "", + config: { + multiPicker: true, + allowEdit: false } + } + vm.labels = {}; - function openViewPicker() { - const controlPicker = { - title: "Select view", - section: "settings", - treeAlias: "files", - entityType: "file", - onlyInitialized: false, - filter: function (i) { - if (i.name.indexOf(".html") === -1 && - i.name.indexOf(".htm") === -1) { - return true; - } - }, - filterCssClass: "not-allowed", - select: function (node) { - const id = decodeURIComponent(node.id.replace(/\+/g, " ")); - vm.package.packageView = id; - editorService.close(); - }, - close: function () { - editorService.close(); - } - }; - editorService.treePicker(controlPicker); - } + vm.versionRegex = /^(\d+\.)(\d+\.)(\*|\d+)$/; - function removePackageView() { - vm.package.packageView = null; - } + vm.aceOption = { + mode: "xml", + theme: "chrome", + showPrintMargin: false, + advanced: { + fontSize: '14px', + enableSnippets: true, + enableBasicAutocompletion: true, + enableLiveAutocompletion: false + }, + onLoad: function (_editor) { + vm.editor = _editor; - function selectDocumentType(doctype) { + vm.editor.setValue(vm.package.actions); + } + }; - // Check if the document type is already selected. - var index = vm.package.documentTypes.indexOf(doctype.id); + function onInit() { - if (index === -1) { - vm.package.documentTypes.push(doctype.id); - } else { - vm.package.documentTypes.splice(index, 1); - } - } + if (create) { + // Pre populate package with some values + packageResource.getEmpty().then(scaffold => { + vm.package = scaffold; - function selectMediaType(mediatype) { + loadResources(); - // Check if the document type is already selected. - var index = vm.package.mediaTypes.indexOf(mediatype.id); + vm.loading = false; + }); - if (index === -1) { - vm.package.mediaTypes.push(mediatype.id); - } else { - vm.package.mediaTypes.splice(index, 1); + localizationService.localizeMany(["general_create", "packager_includeAllChildNodes"]).then(function (values) { + vm.labels.button = values[0]; + vm.labels.includeAllChildNodes = values[1]; + }); + } else { + // Load package + packageResource.getCreatedById(packageId).then(createdPackage => { + vm.package = createdPackage; + + loadResources(); + + vm.loading = false; + + // Get render model for content node + if (vm.package.contentNodeId) { + entityResource.getById(vm.package.contentNodeId, "Document") + .then((entity) => { + vm.contentNodeDisplayModel = entity; + }); } - } - function selectTemplate(template) { + vm.mediaPickerModel.value = vm.package.mediaUdis.join(','); + }); - // Check if the template is already selected. - var index = vm.package.templates.indexOf(template.id); - if (index === -1) { - vm.package.templates.push(template.id); - } else { - vm.package.templates.splice(index, 1); - } - } + localizationService.localizeMany(["buttons_save", "packager_includeAllChildNodes"]).then(function (values) { + vm.labels.button = values[0]; + vm.labels.includeAllChildNodes = values[1]; + }); + } + } - function selectStyleSheet(stylesheet) { + function loadResources() { - // Check if the style sheet is already selected. - var index = vm.package.stylesheets.indexOf(stylesheet.name); + // Get all document types + entityResource.getAll("DocumentType").then(documentTypes => { + // a package stores the id as a string so we + // need to convert all ids to string for comparison + documentTypes.forEach(documentType => { + documentType.id = documentType.id.toString(); + documentType.selected = vm.package.documentTypes.indexOf(documentType.id) !== -1; + }); + vm.documentTypes = documentTypes; + }); - if (index === -1) { - vm.package.stylesheets.push(stylesheet.name); - } else { - vm.package.stylesheets.splice(index, 1); - } - } + // Get all media types + entityResource.getAll("MediaType").then(mediaTypes => { + // a package stores the id as a string so we + // need to convert all ids to string for comparison + mediaTypes.forEach(mediaType => { + mediaType.id = mediaType.id.toString(); + mediaType.selected = vm.package.mediaTypes.indexOf(mediaType.id) !== -1; + }); + vm.mediaTypes = mediaTypes; + }); - function selectMacro(macro) { + // Get all templates + entityResource.getAll("Template").then(templates => { + // a package stores the id as a string so we + // need to convert all ids to string for comparison + templates.forEach(template => { + template.id = template.id.toString(); + template.selected = vm.package.templates.indexOf(template.id) >= 0; + }); + vm.templates = templates; + }); - // Check if the macro is already selected. - var index = vm.package.macros.indexOf(macro.id); + // Get all stylesheets + entityResource.getAll("Stylesheet").then(stylesheets => { + stylesheets.forEach(stylesheet => { + stylesheet.selected = vm.package.stylesheets.indexOf(stylesheet.path) >= 0; + }); + vm.stylesheets = stylesheets; + }); - if (index === -1) { - vm.package.macros.push(macro.id); - } else { - vm.package.macros.splice(index, 1); - } - } + // Get all scripts + entityResource.getAll("Script").then(scripts => { + scripts.forEach(script => { + script.selected = vm.package.scripts.indexOf(script.path) >= 0; + }); + vm.scripts = scripts; + }); - function selectLanguage(language) { + // Get all partial views + entityResource.getAll("PartialView").then(partialViews => { + partialViews.forEach(view => { + view.selected = vm.package.partialViews.indexOf(view.path) >= 0; + }); + vm.partialViews = partialViews; + }); - // Check if the language is already selected. - var index = vm.package.languages.indexOf(language.id); + // Get all macros + entityResource.getAll("Macro").then(macros => { + // a package stores the id as a string so we + // need to convert all ids to string for comparison + macros.forEach(macro => { + macro.id = macro.id.toString(); + macro.selected = vm.package.macros.indexOf(macro.id) !== -1; + }); + vm.macros = macros; + }); - if (index === -1) { - vm.package.languages.push(language.id); - } else { - vm.package.languages.splice(index, 1); - } - } + // Get all languages + entityResource.getAll("Language").then(languages => { + // a package stores the id as a string so we + // need to convert all ids to string for comparison + languages.forEach(language => { + language.id = language.id.toString(); + language.selected = vm.package.languages.indexOf(language.id) !== -1; + }); + vm.languages = languages; + }); - function selectDictionaryItem(dictionaryItem) { + // Get all dictionary items + entityResource.getAll("DictionaryItem").then(dictionaryItems => { + // a package stores the id as a string so we + // need to convert all ids to string for comparison + dictionaryItems.forEach(dictionaryItem => { + dictionaryItem.id = dictionaryItem.id.toString(); + dictionaryItem.selected = vm.package.dictionaryItems.indexOf(dictionaryItem.id) !== -1; + }); + vm.dictionaryItems = dictionaryItems; + }); - // Check if the dictionary item is already selected. - var index = vm.package.dictionaryItems.indexOf(dictionaryItem.id); - - if (index === -1) { - vm.package.dictionaryItems.push(dictionaryItem.id); - } else { - vm.package.dictionaryItems.splice(index, 1); - } - } - - function selectDataType(dataType) { - - // Check if the dictionary item is already selected. - var index = vm.package.dataTypes.indexOf(dataType.id); - - if (index === -1) { - vm.package.dataTypes.push(dataType.id); - } else { - vm.package.dataTypes.splice(index, 1); - } - } - - function getVals(array) { - var vals = []; - for (var i = 0; i < array.length; i++) { - vals.push({ value: array[i] }); - } - return vals; - } - - onInit(); + // Get all data types + entityResource.getAll("DataType").then(dataTypes => { + // a package stores the id as a string so we + // need to convert all ids to string for comparison + dataTypes.forEach(dataType => { + dataType.id = dataType.id.toString(); + dataType.selected = vm.package.dataTypes.indexOf(dataType.id) !== -1; + }); + vm.dataTypes = dataTypes; + }); } - angular.module("umbraco").controller("Umbraco.Editors.Packages.EditController", EditController); + function downloadFile(id) { + var url = umbRequestHelper.getApiUrl( + "packageApiBaseUrl", + "DownloadCreatedPackage", + { id: id }); + + umbRequestHelper.downloadFile(url).then(function () { + + }); + } + + function back() { + $location.path("packages/packages/created").search("create", null).search("packageId", null); + } + + function createOrUpdatePackage(editPackageForm) { + + // Split by comma and remove empty entries + vm.package.mediaUdis = vm.mediaPickerModel.value.split(",").filter(i => i); + if (formHelper.submitForm({ formCtrl: editPackageForm, scope: $scope })) { + + vm.buttonState = "busy"; + + packageResource.savePackage(vm.package).then((updatedPackage) => { + + vm.package = updatedPackage; + vm.buttonState = "success"; + + formHelper.resetForm({ scope: $scope, formCtrl: editPackageForm }); + + if (create) { + //if we are creating, then redirect to the correct url and reload + $location.path("packages/packages/edit/" + vm.package.id).search("create", null); + //don't add a browser history for this + $location.replace(); + } + + }, function (err) { + formHelper.resetForm({ scope: $scope, formCtrl: editPackageForm, hasErrors: true }); + formHelper.handleError(err); + vm.buttonState = "error"; + }); + } + } + + function removeContentItem() { + vm.package.contentNodeId = null; + } + + function openContentPicker() { + const contentPicker = { + submit: function (model) { + if (model.selection && model.selection.length > 0) { + vm.package.contentNodeId = model.selection[0].id.toString(); + vm.contentNodeDisplayModel = model.selection[0]; + } + editorService.close(); + }, + close: function () { + editorService.close(); + } + }; + editorService.contentPicker(contentPicker); + } + + function openViewPicker() { + const controlPicker = { + title: "Select view", + section: "settings", + treeAlias: "files", + entityType: "file", + onlyInitialized: false, + filter: function (i) { + if (i.name.indexOf(".html") === -1 && + i.name.indexOf(".htm") === -1) { + return true; + } + }, + filterCssClass: "not-allowed", + select: function (node) { + const id = decodeURIComponent(node.id.replace(/\+/g, " ")); + vm.package.packageView = id; + editorService.close(); + }, + close: function () { + editorService.close(); + } + }; + editorService.treePicker(controlPicker); + } + + function removePackageView() { + vm.package.packageView = null; + } + + function selectDocumentType(doctype) { + + // Check if the document type is already selected. + var index = vm.package.documentTypes.indexOf(doctype.id); + + if (index === -1) { + vm.package.documentTypes.push(doctype.id); + } else { + vm.package.documentTypes.splice(index, 1); + } + } + + function selectMediaType(mediatype) { + + // Check if the document type is already selected. + var index = vm.package.mediaTypes.indexOf(mediatype.id); + + if (index === -1) { + vm.package.mediaTypes.push(mediatype.id); + } else { + vm.package.mediaTypes.splice(index, 1); + } + } + + function selectTemplate(template) { + + // Check if the template is already selected. + var index = vm.package.templates.indexOf(template.id); + + if (index === -1) { + vm.package.templates.push(template.id); + } else { + vm.package.templates.splice(index, 1); + } + } + + function selectStyleSheet(stylesheet) { + + // Check if the style sheet is already selected. + var index = vm.package.stylesheets.indexOf(stylesheet.path); + + if (index === -1) { + vm.package.stylesheets.push(stylesheet.path); + } else { + vm.package.stylesheets.splice(index, 1); + } + } + + function selectScript(script) { + + // Check if the script is already selected. + var index = vm.package.scripts.indexOf(script.path); + + if (index === -1) { + vm.package.scripts.push(script.path); + } else { + vm.package.scripts.splice(index, 1); + } + } + + function selectPartialView(view) { + + // Check if the view is already selected. + var index = vm.package.partialViews.indexOf(view.path); + + if (index === -1) { + vm.package.partialViews.push(view.path); + } else { + vm.package.partialViews.splice(index, 1); + } + } + + function selectMacro(macro) { + + // Check if the macro is already selected. + var index = vm.package.macros.indexOf(macro.id); + + if (index === -1) { + vm.package.macros.push(macro.id); + } else { + vm.package.macros.splice(index, 1); + } + } + + function selectLanguage(language) { + + // Check if the language is already selected. + var index = vm.package.languages.indexOf(language.id); + + if (index === -1) { + vm.package.languages.push(language.id); + } else { + vm.package.languages.splice(index, 1); + } + } + + function selectDictionaryItem(dictionaryItem) { + + // Check if the dictionary item is already selected. + var index = vm.package.dictionaryItems.indexOf(dictionaryItem.id); + + if (index === -1) { + vm.package.dictionaryItems.push(dictionaryItem.id); + } else { + vm.package.dictionaryItems.splice(index, 1); + } + } + + function selectDataType(dataType) { + + // Check if the dictionary item is already selected. + var index = vm.package.dataTypes.indexOf(dataType.id); + + if (index === -1) { + vm.package.dataTypes.push(dataType.id); + } else { + vm.package.dataTypes.splice(index, 1); + } + } + + function getVals(array) { + var vals = []; + for (var i = 0; i < array.length; i++) { + vals.push({ value: array[i] }); + } + return vals; + } + + onInit(); + + } + + angular.module("umbraco").controller("Umbraco.Editors.Packages.EditController", EditController); })(); diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/edit.html b/src/Umbraco.Web.UI.Client/src/views/packages/edit.html index 8a8ff0fb38..578117a469 100644 --- a/src/Umbraco.Web.UI.Client/src/views/packages/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/packages/edit.html @@ -1,177 +1,193 @@
-
+ - + - - + + - + - + -
+
-
- Package Content -
+
+ Package Content +
-
+
- + - - + - + - - + + - + - + - - - + + + - - - + + + - -
- - -
-
+ +
+ + +
+
- -
- - -
-
+ +
+ + +
+
- -
- - -
-
+ +
+ + +
+
- -
- - -
-
+ +
+ + +
+
- -
- - -
-
+ +
+ + +
+
- -
- - -
-
+ +
+ + +
+
- -
- - -
-
+ +
+ + +
+
- -
- - -
-
+ +
+ + +
+
-
+ +
+ + +
+
-
+ +
+ + +
+
- +
- +
- +
- - + - - + - + + - + + -
+ - + + +
+ +