From 944c8d59d764cf99a255c7acdda57f5dab56c92e Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 11 Feb 2019 15:30:11 +0100 Subject: [PATCH 1/5] Need to clone the object before removing $-prefixed variables. Otherwise we are modifying the same data as the views are using --- src/Umbraco.Core/Constants-Applications.cs | 9 +- .../Migrations/Install/DatabaseDataCreator.cs | 4 +- src/Umbraco.Tests/Testing/UmbracoTestBase.cs | 1 + .../dashboard/dashboard.tabs.controller.js | 99 ------------------- .../dashboard/forms/formsdashboardintro.html | 8 -- src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 1 + .../Umbraco/config/lang/en_us.xml | 3 +- src/Umbraco.Web/Dashboards/FormsDashboard.cs | 3 +- src/Umbraco.Web/Runtime/WebRuntimeComposer.cs | 1 + .../Trees/FormsBackOfficeSection.cs | 14 +++ src/Umbraco.Web/Trees/FormsTreeController.cs | 27 +++++ src/Umbraco.Web/Umbraco.Web.csproj | 2 + 12 files changed, 57 insertions(+), 115 deletions(-) create mode 100644 src/Umbraco.Web/Trees/FormsBackOfficeSection.cs create mode 100644 src/Umbraco.Web/Trees/FormsTreeController.cs diff --git a/src/Umbraco.Core/Constants-Applications.cs b/src/Umbraco.Core/Constants-Applications.cs index 2d4042fad0..e66df3a5f9 100644 --- a/src/Umbraco.Core/Constants-Applications.cs +++ b/src/Umbraco.Core/Constants-Applications.cs @@ -45,7 +45,7 @@ /// /// Application alias for the forms section. /// - public const string Forms = "forms"; + public const string FormsInstaller = "formsInstaller"; } /// @@ -77,7 +77,7 @@ /// alias for the macro tree. /// public const string Macros = "macros"; - + /// /// alias for the datatype tree. /// @@ -92,7 +92,7 @@ /// alias for the dictionary tree. /// public const string Dictionary = "dictionary"; - + public const string Stylesheets = "stylesheets"; /// @@ -121,7 +121,7 @@ public const string Templates = "templates"; public const string RelationTypes = "relationTypes"; - + public const string Languages = "languages"; /// @@ -138,6 +138,7 @@ /// alias for the users tree. /// public const string Users = "users"; + public const string Forms = "formsInstaller"; public const string Scripts = "scripts"; diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index 7f7229ccd6..055b899231 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -189,13 +189,13 @@ namespace Umbraco.Core.Migrations.Install _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Members }); _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Settings }); _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Users }); - _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Forms }); + _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.FormsInstaller }); _database.Insert(new UserGroup2AppDto { UserGroupId = 2, AppAlias = Constants.Applications.Content }); _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.Content }); _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.Media }); - _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.Forms }); + _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.FormsInstaller }); _database.Insert(new UserGroup2AppDto { UserGroupId = 4, AppAlias = Constants.Applications.Translation }); } diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index c404e0404d..a868245940 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -228,6 +228,7 @@ namespace Umbraco.Tests.Testing .Append() .Append() .Append() + .Append() .Append(); Composition.RegisterUnique(); diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js b/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js index ed3d6ded33..e801e2cc58 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js @@ -192,7 +192,6 @@ function FormsController($scope, $route, $cookies, packageResource, localization function Video_player (videoId) { // Get dom elements this.container = document.getElementById(videoId); - this.video = this.container.getElementsByTagName('video')[0]; //Create controls this.controls = document.createElement('div'); @@ -215,104 +214,6 @@ function FormsController($scope, $route, $cookies, packageResource, localization this.controls.appendChild(this.loader); this.loader.appendChild(this.progress_bar); } - - - Video_player.prototype - .seeking = function() { - // get the value of the seekbar (hidden input[type="range"]) - var time = this.video.duration * (this.seek_bar.value / 100); - - // Update video to seekbar value - this.video.currentTime = time; - }; - - // Stop video when user initiates seeking - Video_player.prototype - .start_seek = function() { - this.video.pause(); - }; - - // Start video when user stops seeking - Video_player.prototype - .stop_seek = function() { - this.video.play(); - }; - - // Update the progressbar (span.loader) according to video.currentTime - Video_player.prototype - .update_progress_bar = function() { - // Get video progress in % - var value = (100 / this.video.duration) * this.video.currentTime; - - // Update progressbar - this.progress_bar.style.width = value + '%'; - }; - - // Bind progressbar to mouse when seeking - Video_player.prototype - .handle_mouse_move = function(event) { - // Get position of progressbar relative to browser window - var pos = this.progress_bar.getBoundingClientRect().left; - - // Make sure event is reckonized cross-browser - event = event || window.event; - - // Update progressbar - this.progress_bar.style.width = (event.clientX - pos) + "px"; - }; - - // Eventlisteners for seeking - Video_player.prototype - .video_event_handler = function(videoPlayer, interval) { - // Update the progress bar - var animate_progress_bar = setInterval(function () { - videoPlayer.update_progress_bar(); - }, interval); - - // Fire when input value changes (user seeking) - videoPlayer.seek_bar - .addEventListener("change", function() { - videoPlayer.seeking(); - }); - - // Fire when user clicks on seekbar - videoPlayer.seek_bar - .addEventListener("mousedown", function (clickEvent) { - // Pause video playback - videoPlayer.start_seek(); - - // Stop updating progressbar according to video progress - clearInterval(animate_progress_bar); - - // Update progressbar to where user clicks - videoPlayer.handle_mouse_move(clickEvent); - - // Bind progressbar to cursor - window.onmousemove = function(moveEvent){ - videoPlayer.handle_mouse_move(moveEvent); - }; - }); - - // Fire when user releases seekbar - videoPlayer.seek_bar - .addEventListener("mouseup", function () { - - // Unbind progressbar from cursor - window.onmousemove = null; - - // Start video playback - videoPlayer.stop_seek(); - - // Animate the progressbar - animate_progress_bar = setInterval(function () { - videoPlayer.update_progress_bar(); - }, interval); - }); - }; - - - var videoPlayer = new Video_player('video_1'); - videoPlayer.video_event_handler(videoPlayer, 17); } angular.module("umbraco").controller("Umbraco.Dashboard.FormsDashboardController", FormsController); diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html index 3b382367c4..c18e7f4ccf 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html @@ -8,14 +8,6 @@
-
- -
-

Create forms using an intuitive drag and drop interface. From simple contact forms that sends e-mails to advanced questionaires that integrate with CRM systems. Your clients will love it!

Courier Developer Forms + Forms Help Umbraco Configuration Wizard Media diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml index 852abcd5d8..b9aa3b6ece 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -1247,6 +1247,7 @@ To manage your website, simply open the Umbraco back office and start adding con Content Forms + Forms Media Members Packages @@ -1388,7 +1389,7 @@ To manage your website, simply open the Umbraco back office and start adding con Styles The CSS that should be applied in the rich text editor, e.g. "color:red;" Code - Rich Text Editor + Rich Text Editor Failed to delete template with ID %0% diff --git a/src/Umbraco.Web/Dashboards/FormsDashboard.cs b/src/Umbraco.Web/Dashboards/FormsDashboard.cs index a3e1123369..bb21a04fdc 100644 --- a/src/Umbraco.Web/Dashboards/FormsDashboard.cs +++ b/src/Umbraco.Web/Dashboards/FormsDashboard.cs @@ -1,4 +1,5 @@ using System; +using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Dashboards; @@ -9,7 +10,7 @@ namespace Umbraco.Web.Dashboards { public string Alias => "formsInstall"; - public string[] Sections => new [] { "forms" }; + public string[] Sections => new [] { Constants.Applications.FormsInstaller }; public string View => "views/dashboard/forms/formsdashboardintro.html"; diff --git a/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs b/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs index 3afe6aa397..52373184b4 100644 --- a/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs +++ b/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs @@ -220,6 +220,7 @@ namespace Umbraco.Web.Runtime .Append() .Append() .Append() + .Append() .Append(); // register core CMS dashboards and 3rd party types - will be ordered by weight attribute & merged with package.manifest dashboards diff --git a/src/Umbraco.Web/Trees/FormsBackOfficeSection.cs b/src/Umbraco.Web/Trees/FormsBackOfficeSection.cs new file mode 100644 index 0000000000..681fe61993 --- /dev/null +++ b/src/Umbraco.Web/Trees/FormsBackOfficeSection.cs @@ -0,0 +1,14 @@ +using Umbraco.Core; +using Umbraco.Core.Models.Trees; + +namespace Umbraco.Web.Trees +{ + /// + /// Defines the back office media section + /// + public class FormsBackOfficeSection : IBackOfficeSection + { + public string Alias => Constants.Applications.FormsInstaller; + public string Name => "Forms"; + } +} diff --git a/src/Umbraco.Web/Trees/FormsTreeController.cs b/src/Umbraco.Web/Trees/FormsTreeController.cs new file mode 100644 index 0000000000..2c6885cf97 --- /dev/null +++ b/src/Umbraco.Web/Trees/FormsTreeController.cs @@ -0,0 +1,27 @@ +using System.Net.Http.Formatting; +using Umbraco.Web.Models.Trees; +using Umbraco.Web.Mvc; +using Umbraco.Web.WebApi.Filters; +using Constants = Umbraco.Core.Constants; + +namespace Umbraco.Web.Trees +{ + [UmbracoTreeAuthorize(Constants.Trees.Forms)] + [Tree(Constants.Applications.FormsInstaller, Constants.Trees.Forms, SortOrder = 0, IsSingleNodeTree = true)] + [PluginController("UmbracoTrees")] + [CoreTree] + public class FormsTreeController : TreeController + { + protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) + { + //full screen app without tree nodes + return TreeNodeCollection.Empty; + } + + protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) + { + //doesn't have a menu, this is a full screen app without tree nodes + return MenuItemCollection.Empty; + } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 8699540e4b..23ae727c35 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -214,6 +214,8 @@ + + From 60ca85fe25e4874adfff3bd853990481ef6139e5 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 11 Feb 2019 15:30:11 +0100 Subject: [PATCH 2/5] Introduced the forms section in the sections menu. --- src/Umbraco.Core/Constants-Applications.cs | 9 +- .../Migrations/Install/DatabaseDataCreator.cs | 4 +- src/Umbraco.Tests/Testing/UmbracoTestBase.cs | 1 + .../dashboard/dashboard.tabs.controller.js | 99 ------------------- .../dashboard/forms/formsdashboardintro.html | 8 -- src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 1 + .../Umbraco/config/lang/en_us.xml | 3 +- src/Umbraco.Web/Dashboards/FormsDashboard.cs | 3 +- src/Umbraco.Web/Runtime/WebRuntimeComposer.cs | 1 + .../Trees/FormsBackOfficeSection.cs | 14 +++ src/Umbraco.Web/Trees/FormsTreeController.cs | 27 +++++ src/Umbraco.Web/Umbraco.Web.csproj | 2 + 12 files changed, 57 insertions(+), 115 deletions(-) create mode 100644 src/Umbraco.Web/Trees/FormsBackOfficeSection.cs create mode 100644 src/Umbraco.Web/Trees/FormsTreeController.cs diff --git a/src/Umbraco.Core/Constants-Applications.cs b/src/Umbraco.Core/Constants-Applications.cs index 2d4042fad0..e66df3a5f9 100644 --- a/src/Umbraco.Core/Constants-Applications.cs +++ b/src/Umbraco.Core/Constants-Applications.cs @@ -45,7 +45,7 @@ /// /// Application alias for the forms section. /// - public const string Forms = "forms"; + public const string FormsInstaller = "formsInstaller"; } /// @@ -77,7 +77,7 @@ /// alias for the macro tree. /// public const string Macros = "macros"; - + /// /// alias for the datatype tree. /// @@ -92,7 +92,7 @@ /// alias for the dictionary tree. ///
public const string Dictionary = "dictionary"; - + public const string Stylesheets = "stylesheets"; /// @@ -121,7 +121,7 @@ public const string Templates = "templates"; public const string RelationTypes = "relationTypes"; - + public const string Languages = "languages"; /// @@ -138,6 +138,7 @@ /// alias for the users tree. /// public const string Users = "users"; + public const string Forms = "formsInstaller"; public const string Scripts = "scripts"; diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index 7f7229ccd6..055b899231 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -189,13 +189,13 @@ namespace Umbraco.Core.Migrations.Install _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Members }); _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Settings }); _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Users }); - _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Forms }); + _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.FormsInstaller }); _database.Insert(new UserGroup2AppDto { UserGroupId = 2, AppAlias = Constants.Applications.Content }); _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.Content }); _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.Media }); - _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.Forms }); + _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.FormsInstaller }); _database.Insert(new UserGroup2AppDto { UserGroupId = 4, AppAlias = Constants.Applications.Translation }); } diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index c404e0404d..a868245940 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -228,6 +228,7 @@ namespace Umbraco.Tests.Testing .Append() .Append() .Append() + .Append() .Append(); Composition.RegisterUnique(); diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js b/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js index ed3d6ded33..e801e2cc58 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/dashboard.tabs.controller.js @@ -192,7 +192,6 @@ function FormsController($scope, $route, $cookies, packageResource, localization function Video_player (videoId) { // Get dom elements this.container = document.getElementById(videoId); - this.video = this.container.getElementsByTagName('video')[0]; //Create controls this.controls = document.createElement('div'); @@ -215,104 +214,6 @@ function FormsController($scope, $route, $cookies, packageResource, localization this.controls.appendChild(this.loader); this.loader.appendChild(this.progress_bar); } - - - Video_player.prototype - .seeking = function() { - // get the value of the seekbar (hidden input[type="range"]) - var time = this.video.duration * (this.seek_bar.value / 100); - - // Update video to seekbar value - this.video.currentTime = time; - }; - - // Stop video when user initiates seeking - Video_player.prototype - .start_seek = function() { - this.video.pause(); - }; - - // Start video when user stops seeking - Video_player.prototype - .stop_seek = function() { - this.video.play(); - }; - - // Update the progressbar (span.loader) according to video.currentTime - Video_player.prototype - .update_progress_bar = function() { - // Get video progress in % - var value = (100 / this.video.duration) * this.video.currentTime; - - // Update progressbar - this.progress_bar.style.width = value + '%'; - }; - - // Bind progressbar to mouse when seeking - Video_player.prototype - .handle_mouse_move = function(event) { - // Get position of progressbar relative to browser window - var pos = this.progress_bar.getBoundingClientRect().left; - - // Make sure event is reckonized cross-browser - event = event || window.event; - - // Update progressbar - this.progress_bar.style.width = (event.clientX - pos) + "px"; - }; - - // Eventlisteners for seeking - Video_player.prototype - .video_event_handler = function(videoPlayer, interval) { - // Update the progress bar - var animate_progress_bar = setInterval(function () { - videoPlayer.update_progress_bar(); - }, interval); - - // Fire when input value changes (user seeking) - videoPlayer.seek_bar - .addEventListener("change", function() { - videoPlayer.seeking(); - }); - - // Fire when user clicks on seekbar - videoPlayer.seek_bar - .addEventListener("mousedown", function (clickEvent) { - // Pause video playback - videoPlayer.start_seek(); - - // Stop updating progressbar according to video progress - clearInterval(animate_progress_bar); - - // Update progressbar to where user clicks - videoPlayer.handle_mouse_move(clickEvent); - - // Bind progressbar to cursor - window.onmousemove = function(moveEvent){ - videoPlayer.handle_mouse_move(moveEvent); - }; - }); - - // Fire when user releases seekbar - videoPlayer.seek_bar - .addEventListener("mouseup", function () { - - // Unbind progressbar from cursor - window.onmousemove = null; - - // Start video playback - videoPlayer.stop_seek(); - - // Animate the progressbar - animate_progress_bar = setInterval(function () { - videoPlayer.update_progress_bar(); - }, interval); - }); - }; - - - var videoPlayer = new Video_player('video_1'); - videoPlayer.video_event_handler(videoPlayer, 17); } angular.module("umbraco").controller("Umbraco.Dashboard.FormsDashboardController", FormsController); diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html index 3b382367c4..c18e7f4ccf 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/forms/formsdashboardintro.html @@ -8,14 +8,6 @@
-
- -
-

Create forms using an intuitive drag and drop interface. From simple contact forms that sends e-mails to advanced questionaires that integrate with CRM systems. Your clients will love it!

Courier Developer Forms + Forms Help Umbraco Configuration Wizard Media diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml index 852abcd5d8..b9aa3b6ece 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -1247,6 +1247,7 @@ To manage your website, simply open the Umbraco back office and start adding con Content Forms + Forms Media Members Packages @@ -1388,7 +1389,7 @@ To manage your website, simply open the Umbraco back office and start adding con Styles The CSS that should be applied in the rich text editor, e.g. "color:red;" Code - Rich Text Editor + Rich Text Editor Failed to delete template with ID %0% diff --git a/src/Umbraco.Web/Dashboards/FormsDashboard.cs b/src/Umbraco.Web/Dashboards/FormsDashboard.cs index a3e1123369..bb21a04fdc 100644 --- a/src/Umbraco.Web/Dashboards/FormsDashboard.cs +++ b/src/Umbraco.Web/Dashboards/FormsDashboard.cs @@ -1,4 +1,5 @@ using System; +using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Dashboards; @@ -9,7 +10,7 @@ namespace Umbraco.Web.Dashboards { public string Alias => "formsInstall"; - public string[] Sections => new [] { "forms" }; + public string[] Sections => new [] { Constants.Applications.FormsInstaller }; public string View => "views/dashboard/forms/formsdashboardintro.html"; diff --git a/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs b/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs index 3afe6aa397..52373184b4 100644 --- a/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs +++ b/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs @@ -220,6 +220,7 @@ namespace Umbraco.Web.Runtime .Append() .Append() .Append() + .Append() .Append(); // register core CMS dashboards and 3rd party types - will be ordered by weight attribute & merged with package.manifest dashboards diff --git a/src/Umbraco.Web/Trees/FormsBackOfficeSection.cs b/src/Umbraco.Web/Trees/FormsBackOfficeSection.cs new file mode 100644 index 0000000000..681fe61993 --- /dev/null +++ b/src/Umbraco.Web/Trees/FormsBackOfficeSection.cs @@ -0,0 +1,14 @@ +using Umbraco.Core; +using Umbraco.Core.Models.Trees; + +namespace Umbraco.Web.Trees +{ + /// + /// Defines the back office media section + /// + public class FormsBackOfficeSection : IBackOfficeSection + { + public string Alias => Constants.Applications.FormsInstaller; + public string Name => "Forms"; + } +} diff --git a/src/Umbraco.Web/Trees/FormsTreeController.cs b/src/Umbraco.Web/Trees/FormsTreeController.cs new file mode 100644 index 0000000000..2c6885cf97 --- /dev/null +++ b/src/Umbraco.Web/Trees/FormsTreeController.cs @@ -0,0 +1,27 @@ +using System.Net.Http.Formatting; +using Umbraco.Web.Models.Trees; +using Umbraco.Web.Mvc; +using Umbraco.Web.WebApi.Filters; +using Constants = Umbraco.Core.Constants; + +namespace Umbraco.Web.Trees +{ + [UmbracoTreeAuthorize(Constants.Trees.Forms)] + [Tree(Constants.Applications.FormsInstaller, Constants.Trees.Forms, SortOrder = 0, IsSingleNodeTree = true)] + [PluginController("UmbracoTrees")] + [CoreTree] + public class FormsTreeController : TreeController + { + protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) + { + //full screen app without tree nodes + return TreeNodeCollection.Empty; + } + + protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) + { + //doesn't have a menu, this is a full screen app without tree nodes + return MenuItemCollection.Empty; + } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 8699540e4b..23ae727c35 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -214,6 +214,8 @@ + + From 1a1222905b4967c25773448949b28d673399d1b3 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 Feb 2019 12:22:36 +1100 Subject: [PATCH 3/5] reverts the formsInstaller alias, fixes the ApplicationTreeController to allow full screen sections without trees, removes the forms tree controller --- src/Umbraco.Core/Constants-Applications.cs | 3 +-- .../Migrations/Install/DatabaseDataCreator.cs | 4 +-- src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 1 - .../Umbraco/config/lang/en_us.xml | 1 - src/Umbraco.Web/Dashboards/FormsDashboard.cs | 2 +- src/Umbraco.Web/Editors/SectionController.cs | 2 +- .../Trees/ApplicationTreeController.cs | 19 ++++++++++--- .../Trees/FormsBackOfficeSection.cs | 2 +- src/Umbraco.Web/Trees/FormsTreeController.cs | 27 ------------------- src/Umbraco.Web/Umbraco.Web.csproj | 1 - 10 files changed, 21 insertions(+), 41 deletions(-) delete mode 100644 src/Umbraco.Web/Trees/FormsTreeController.cs diff --git a/src/Umbraco.Core/Constants-Applications.cs b/src/Umbraco.Core/Constants-Applications.cs index e66df3a5f9..b53a2b8eaf 100644 --- a/src/Umbraco.Core/Constants-Applications.cs +++ b/src/Umbraco.Core/Constants-Applications.cs @@ -45,7 +45,7 @@ /// /// Application alias for the forms section. /// - public const string FormsInstaller = "formsInstaller"; + public const string Forms = "forms"; } /// @@ -138,7 +138,6 @@ /// alias for the users tree. /// public const string Users = "users"; - public const string Forms = "formsInstaller"; public const string Scripts = "scripts"; diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index 055b899231..7f7229ccd6 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -189,13 +189,13 @@ namespace Umbraco.Core.Migrations.Install _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Members }); _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Settings }); _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Users }); - _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.FormsInstaller }); + _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Forms }); _database.Insert(new UserGroup2AppDto { UserGroupId = 2, AppAlias = Constants.Applications.Content }); _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.Content }); _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.Media }); - _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.FormsInstaller }); + _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.Forms }); _database.Insert(new UserGroup2AppDto { UserGroupId = 4, AppAlias = Constants.Applications.Translation }); } diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index 91a4d9378c..548d6932a6 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -1244,7 +1244,6 @@ To manage your website, simply open the Umbraco back office and start adding con Courier Developer Forms - Forms Help Umbraco Configuration Wizard Media diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml index b9aa3b6ece..7dcd101aff 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -1247,7 +1247,6 @@ To manage your website, simply open the Umbraco back office and start adding con Content Forms - Forms Media Members Packages diff --git a/src/Umbraco.Web/Dashboards/FormsDashboard.cs b/src/Umbraco.Web/Dashboards/FormsDashboard.cs index bb21a04fdc..867e8af3aa 100644 --- a/src/Umbraco.Web/Dashboards/FormsDashboard.cs +++ b/src/Umbraco.Web/Dashboards/FormsDashboard.cs @@ -10,7 +10,7 @@ namespace Umbraco.Web.Dashboards { public string Alias => "formsInstall"; - public string[] Sections => new [] { Constants.Applications.FormsInstaller }; + public string[] Sections => new [] { Constants.Applications.Forms }; public string View => "views/dashboard/forms/formsdashboardintro.html"; diff --git a/src/Umbraco.Web/Editors/SectionController.cs b/src/Umbraco.Web/Editors/SectionController.cs index 0a2f17cd15..52034b9c95 100644 --- a/src/Umbraco.Web/Editors/SectionController.cs +++ b/src/Umbraco.Web/Editors/SectionController.cs @@ -43,7 +43,7 @@ namespace Umbraco.Web.Editors // this is a bit nasty since we'll be proxying via the app tree controller but we sort of have to do that // since tree's by nature are controllers and require request contextual data - var appTreeController = new ApplicationTreeController(GlobalSettings, UmbracoContext, SqlContext, Services, AppCaches, Logger, RuntimeState, _treeService, Umbraco) + var appTreeController = new ApplicationTreeController(GlobalSettings, UmbracoContext, SqlContext, Services, AppCaches, Logger, RuntimeState, _treeService, _sectionService, Umbraco) { ControllerContext = ControllerContext }; diff --git a/src/Umbraco.Web/Trees/ApplicationTreeController.cs b/src/Umbraco.Web/Trees/ApplicationTreeController.cs index 162d001e96..b8fe709738 100644 --- a/src/Umbraco.Web/Trees/ApplicationTreeController.cs +++ b/src/Umbraco.Web/Trees/ApplicationTreeController.cs @@ -32,13 +32,15 @@ namespace Umbraco.Web.Trees public class ApplicationTreeController : UmbracoAuthorizedApiController { private readonly ITreeService _treeService; + private readonly ISectionService _sectionService; public ApplicationTreeController(IGlobalSettings globalSettings, UmbracoContext umbracoContext, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, - IRuntimeState runtimeState, ITreeService treeService, UmbracoHelper umbracoHelper) + IRuntimeState runtimeState, ITreeService treeService, ISectionService sectionService, UmbracoHelper umbracoHelper) : base(globalSettings, umbracoContext, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper) { _treeService = treeService; + _sectionService = sectionService; } /// @@ -56,12 +58,21 @@ namespace Umbraco.Web.Trees if (string.IsNullOrEmpty(application)) throw new HttpResponseException(HttpStatusCode.NotFound); + var section = _sectionService.GetByAlias(application); + if (section == null) + throw new HttpResponseException(HttpStatusCode.NotFound); + //find all tree definitions that have the current application alias var groupedTrees = _treeService.GetBySectionGrouped(application, use); var allTrees = groupedTrees.Values.SelectMany(x => x).ToList(); if (allTrees.Count == 0) - throw new HttpResponseException(HttpStatusCode.NotFound); + { + //if there are no trees defined for this section but the section is defined then we can have a simple + //full screen section without trees + var name = Services.TextService.Localize("sections/" + application); + return TreeRootNode.CreateSingleTreeRoot(Constants.System.Root.ToInvariantString(), null, null, name, TreeNodeCollection.Empty, true); + } // handle request for a specific tree / or when there is only one tree if (!tree.IsNullOrWhiteSpace() || allTrees.Count == 1) @@ -101,8 +112,8 @@ namespace Umbraco.Web.Trees return treeRootNode; } - // otherwise it's a section with no tree, aka a fullscreen section - // todo is this true? what if we just failed to TryGetRootNode on all of them? + // otherwise it's a section with all empty trees, aka a fullscreen section + // todo is this true? what if we just failed to TryGetRootNode on all of them? SD: Yes it's true but we should check the result of TryGetRootNode and throw? return TreeRootNode.CreateSingleTreeRoot(Constants.System.Root.ToInvariantString(), null, null, name, TreeNodeCollection.Empty, true); } diff --git a/src/Umbraco.Web/Trees/FormsBackOfficeSection.cs b/src/Umbraco.Web/Trees/FormsBackOfficeSection.cs index 681fe61993..048ed47f11 100644 --- a/src/Umbraco.Web/Trees/FormsBackOfficeSection.cs +++ b/src/Umbraco.Web/Trees/FormsBackOfficeSection.cs @@ -8,7 +8,7 @@ namespace Umbraco.Web.Trees /// public class FormsBackOfficeSection : IBackOfficeSection { - public string Alias => Constants.Applications.FormsInstaller; + public string Alias => Constants.Applications.Forms; public string Name => "Forms"; } } diff --git a/src/Umbraco.Web/Trees/FormsTreeController.cs b/src/Umbraco.Web/Trees/FormsTreeController.cs deleted file mode 100644 index 2c6885cf97..0000000000 --- a/src/Umbraco.Web/Trees/FormsTreeController.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Net.Http.Formatting; -using Umbraco.Web.Models.Trees; -using Umbraco.Web.Mvc; -using Umbraco.Web.WebApi.Filters; -using Constants = Umbraco.Core.Constants; - -namespace Umbraco.Web.Trees -{ - [UmbracoTreeAuthorize(Constants.Trees.Forms)] - [Tree(Constants.Applications.FormsInstaller, Constants.Trees.Forms, SortOrder = 0, IsSingleNodeTree = true)] - [PluginController("UmbracoTrees")] - [CoreTree] - public class FormsTreeController : TreeController - { - protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) - { - //full screen app without tree nodes - return TreeNodeCollection.Empty; - } - - protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) - { - //doesn't have a menu, this is a full screen app without tree nodes - return MenuItemCollection.Empty; - } - } -} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 23ae727c35..6522ac9a05 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -215,7 +215,6 @@ - From c00f805ea2fd8ce511c4ab9c19ab0f78a79e7de5 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 Feb 2019 13:36:32 +1100 Subject: [PATCH 4/5] Fixes dirty tracking on tags editor when it's csv format --- .../tags/umbtagseditor.directive.js | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js index edf54ca034..5131dc3dcb 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js @@ -29,6 +29,8 @@ let typeahead; let tagsHound; + let initLoad = true; + vm.$onInit = onInit; vm.$onChanges = onChanges; vm.$onDestroy = onDestroy; @@ -138,9 +140,17 @@ if (changes.value) { if (!changes.value.isFirstChange() && changes.value.currentValue !== changes.value.previousValue) { - configureViewModel(); - reValidate() - + if (initLoad) { + //this occurs if we have to re-format the model on the init load, so set the flag to false + //so the next time it actually changes we process it. + initLoad = false; + //we need to reset the form since it actually hasn't changed but it will be detected as changed + vm.tagEditorForm.$setPristine(); + } + else { + configureViewModel(); + reValidate(); + } } } } @@ -161,6 +171,7 @@ //json storage vm.viewModel = JSON.parse(vm.value); updateModelValue(vm.viewModel); + return; } else { //csv storage @@ -175,13 +186,15 @@ }); updateModelValue(vm.viewModel); - + return; } } else if (angular.isArray(vm.value)) { vm.viewModel = vm.value; } } + //if we've made it here we haven't had to re-format the model so we'll set this to false + initLoad = false; } function updateModelValue(val) { From 54aa1924c0cee7d39f75fdc8ec32fd6ee413ee12 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 Feb 2019 13:55:50 +1100 Subject: [PATCH 5/5] ok, properly fixes dirty tracking on the tags editor --- .../tags/umbtagseditor.directive.js | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js index 5131dc3dcb..40def728ed 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js @@ -55,7 +55,7 @@ vm.isLoading = false; //ensure that the models are formatted correctly - configureViewModel(); + configureViewModel(true); // Set the visible prompt to -1 to ensure it will not be visible vm.promptIsVisible = "-1"; @@ -140,17 +140,8 @@ if (changes.value) { if (!changes.value.isFirstChange() && changes.value.currentValue !== changes.value.previousValue) { - if (initLoad) { - //this occurs if we have to re-format the model on the init load, so set the flag to false - //so the next time it actually changes we process it. - initLoad = false; - //we need to reset the form since it actually hasn't changed but it will be detected as changed - vm.tagEditorForm.$setPristine(); - } - else { - configureViewModel(); - reValidate(); - } + configureViewModel(); + reValidate(); } } } @@ -164,14 +155,19 @@ $element.find('.tags-' + vm.htmlId).typeahead('destroy'); } - function configureViewModel() { + function configureViewModel(isInitLoad) { if (vm.value) { if (angular.isString(vm.value) && vm.value.length > 0) { if (vm.config.storageType === "Json") { //json storage vm.viewModel = JSON.parse(vm.value); - updateModelValue(vm.viewModel); - return; + + //if this is the first load, we are just re-formatting the underlying model to be consistent + //we don't want to notify the component parent of any changes, that will occur if the user actually + //changes a value. If we notify at this point it will signal a form dirty change which we don't want. + if (!isInitLoad) { + updateModelValue(vm.viewModel); + } } else { //csv storage @@ -185,16 +181,18 @@ return self.indexOf(v) === i; }); - updateModelValue(vm.viewModel); - return; + //if this is the first load, we are just re-formatting the underlying model to be consistent + //we don't want to notify the component parent of any changes, that will occur if the user actually + //changes a value. If we notify at this point it will signal a form dirty change which we don't want. + if (!isInitLoad) { + updateModelValue(vm.viewModel); + } } } else if (angular.isArray(vm.value)) { vm.viewModel = vm.value; } } - //if we've made it here we haven't had to re-format the model so we'll set this to false - initLoad = false; } function updateModelValue(val) {