diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tour.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tour.service.js index 1955cf7219..5d05623b0b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tour.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tour.service.js @@ -19,7 +19,7 @@ function registerAllTours() { return tourResource.getTours().then(function(tourFiles) { angular.forEach(tourFiles, function (tourFile) { - angular.forEach(tourFile, function(newTour) { + angular.forEach(tourFile.tours, function(newTour) { validateTour(newTour); validateTourRegistration(newTour); tours.push(newTour); diff --git a/src/Umbraco.Web/Editors/TourController.cs b/src/Umbraco.Web/Editors/TourController.cs index ad9b6b3430..61acf7dfed 100644 --- a/src/Umbraco.Web/Editors/TourController.cs +++ b/src/Umbraco.Web/Editors/TourController.cs @@ -1,9 +1,13 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.RegularExpressions; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Umbraco.Core.Configuration; using Umbraco.Core.IO; +using Umbraco.Web.Models; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi.Filters; using Constants = Umbraco.Core.Constants; @@ -11,29 +15,54 @@ using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.Editors { [PluginController("UmbracoApi")] - [UmbracoApplicationAuthorize(Constants.Applications.Content)] + [UmbracoApplicationAuthorize(Constants.Applications.Content)] public class TourController : UmbracoAuthorizedJsonController { - //TODO: Strongly type this for final release! - public JArray GetTours() + public IEnumerable GetTours() { - //TODO: Add error checking to this for final release! - - var result = new JArray(); + var result = new List(); if (UmbracoConfig.For.UmbracoSettings().BackOffice.Tours.EnableTours == false) return result; - var tourFiles = Directory.GetFiles( - Path.Combine(IOHelper.MapPath(SystemDirectories.Config), "BackOfficeTours"), "*.json") - .OrderBy(x => x, StringComparer.InvariantCultureIgnoreCase); - foreach (var tourFile in tourFiles) + var coreTourFiles = Directory.GetFiles( + Path.Combine(IOHelper.MapPath(SystemDirectories.Config), "BackOfficeTours"), "*.json"); + + foreach (var tourFile in coreTourFiles) { var contents = File.ReadAllText(tourFile); - result.Add(JArray.Parse(contents)); + + result.Add(new BackOfficeTourFile + { + FileName = Path.GetFileNameWithoutExtension(tourFile), + Tours = JsonConvert.DeserializeObject(contents) + }); } - return result; + //collect all tour files in packges + foreach (var plugin in Directory.EnumerateDirectories(IOHelper.MapPath(SystemDirectories.AppPlugins))) + { + var pluginName = Path.GetFileName(plugin.TrimEnd('\\')); + + foreach (var backofficeDir in Directory.EnumerateDirectories(plugin, "backoffice")) + { + foreach (var tourDir in Directory.EnumerateDirectories(backofficeDir, "tours")) + { + foreach (var tourFile in Directory.EnumerateFiles(tourDir, "*.json")) + { + var contents = File.ReadAllText(tourFile); + result.Add(new BackOfficeTourFile + { + FileName = Path.GetFileNameWithoutExtension(tourFile), + PluginName = pluginName, + Tours = JsonConvert.DeserializeObject(contents) + }); + } + } + } + } + + return result.OrderBy(x => x.FileName, StringComparer.InvariantCultureIgnoreCase); } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Models/BackOfficeTour.cs b/src/Umbraco.Web/Models/BackOfficeTour.cs new file mode 100644 index 0000000000..1e0f345b52 --- /dev/null +++ b/src/Umbraco.Web/Models/BackOfficeTour.cs @@ -0,0 +1,23 @@ +using System; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace Umbraco.Web.Models +{ + [DataContract(Name = "tour", Namespace = "")] + public class BackOfficeTour + { + [DataMember(Name = "name")] + public string Name { get; set; } + [DataMember(Name = "alias")] + public string Alias { get; set; } + [DataMember(Name = "group")] + public string Group { get; set; } + [DataMember(Name = "allowDisable")] + public bool AllowDisable { get; set; } + [DataMember(Name = "steps")] + public BackOfficeTourStep[] Steps { get; set; } + } +} diff --git a/src/Umbraco.Web/Models/BackOfficeTourFile.cs b/src/Umbraco.Web/Models/BackOfficeTourFile.cs new file mode 100644 index 0000000000..69b35c8088 --- /dev/null +++ b/src/Umbraco.Web/Models/BackOfficeTourFile.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace Umbraco.Web.Models +{ + [DataContract(Name = "tourFile", Namespace = "")] + public class BackOfficeTourFile + { + /// + /// The file name for the tour + /// + [DataMember(Name = "fileName")] + public string FileName { get; set; } + + /// + /// The plugin folder that the tour comes from + /// + /// + /// If this is null it means it's a Core tour + /// + [DataMember(Name = "pluginName")] + public string PluginName { get; set; } + + [DataMember(Name = "tours")] + public IEnumerable Tours { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/BackOfficeTourStep.cs b/src/Umbraco.Web/Models/BackOfficeTourStep.cs new file mode 100644 index 0000000000..e0371bf4b5 --- /dev/null +++ b/src/Umbraco.Web/Models/BackOfficeTourStep.cs @@ -0,0 +1,23 @@ +using System.Runtime.Serialization; + +namespace Umbraco.Web.Models +{ + [DataContract(Name = "step", Namespace = "")] + public class BackOfficeTourStep + { + [DataMember(Name = "title")] + public string Title { get; set; } + [DataMember(Name = "content")] + public string Content { get; set; } + [DataMember(Name = "type")] + public string Type { get; set; } + [DataMember(Name = "element")] + public string Element { get; set; } + [DataMember(Name = "elementPreventClick")] + public bool ElementPreventClick { get; set; } + [DataMember(Name = "backdropOpacity")] + public float BackdropOpacity { get; set; } + [DataMember(Name = "event")] + public string Event { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 326ed3baa9..83ed982639 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -371,6 +371,8 @@ + + @@ -428,6 +430,7 @@ +