From 7aeea96e2353414eb69ee63f831be80fd5b6d73b Mon Sep 17 00:00:00 2001 From: Tim Geyssens Date: Fri, 11 Nov 2016 11:45:25 +0100 Subject: [PATCH 001/134] First take localized text into account before the title property when working with tree headers --- src/Umbraco.Web/Trees/TreeController.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web/Trees/TreeController.cs b/src/Umbraco.Web/Trees/TreeController.cs index 0f975a9860..167de70cf7 100644 --- a/src/Umbraco.Web/Trees/TreeController.cs +++ b/src/Umbraco.Web/Trees/TreeController.cs @@ -43,16 +43,18 @@ namespace Umbraco.Web.Trees get { - //if title is defined, return that - if(string.IsNullOrEmpty(_attribute.Title) == false) - return _attribute.Title; + //try to look up a tree header matching the tree alias var localizedLabel = Services.TextService.Localize("treeHeaders/" + _attribute.Alias); - if (string.IsNullOrEmpty(localizedLabel) == false) + if (!string.IsNullOrEmpty(localizedLabel)) return localizedLabel; + //if title is defined, return that + if (!string.IsNullOrEmpty(_attribute.Title)) + return _attribute.Title; + //is returned to signal that a label was not found return "[" + _attribute.Alias + "]"; } From e501f0f612ec8e1d22d8b97b6e833ba50073202c Mon Sep 17 00:00:00 2001 From: bjarnef Date: Tue, 15 Nov 2016 21:26:57 +0100 Subject: [PATCH 002/134] Fix positioning of file icon extension label --- src/Umbraco.Web.UI.Client/src/less/hacks.less | 15 ++++--- .../src/less/property-editors.less | 41 ++++++++++++------- .../fileupload/fileupload.html | 8 ++-- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/hacks.less b/src/Umbraco.Web.UI.Client/src/less/hacks.less index 716cb40256..50a50b598d 100644 --- a/src/Umbraco.Web.UI.Client/src/less/hacks.less +++ b/src/Umbraco.Web.UI.Client/src/less/hacks.less @@ -20,12 +20,17 @@ } .thumbnail { - border-radius: 0px; -} + border-radius: 0; + min-width: 150px; -.thumbnail img { - max-width: 100% !important; - width: 100%; + > a { + display: block; + } + + img { + max-width: 100% !important; + width: 100%; + } } #mapCanvas img { diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 573f218fb1..93abc39987 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -408,6 +408,7 @@ ul.color-picker li a { .gravity-container .viewport { max-width: 600px; + min-width: 250px; } .gravity-container .viewport:hover { @@ -704,28 +705,38 @@ ul.color-picker li a { padding-top: 27px; } -.umb-fileupload .file-icon { +.umb-fileupload .file-icon-wrap { text-align: center; display: block; position: relative; padding: 5px 0; - > .icon { - font-size: 70px; - line-height: 110%; - color: #666; - text-align: center; + /* fit text within container */ + & + span { + word-wrap: break-word; } - > span { - color: #fff; - background: #666; - padding: 1px 3px; - font-size: 12px; - line-height: 130%; - position: absolute; - top: 45px; - left: 110px; + .file-icon { + position: relative; + display: inline-block; + + > .icon { + font-size: 70px; + line-height: 110%; + color: #666; + text-align: center; + } + + > span { + color: #fff; + background: #666; + padding: 1px 3px; + font-size: 12px; + line-height: 130%; + position: absolute; + top: 40px; + left: 35px; + } } } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html index 0905de07f9..77a52381a9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.html @@ -6,9 +6,11 @@ {{file.file}} {{file.file}} - - - .{{file.extension}} + + + + .{{file.extension}} + {{file.file}} From 647d3e87926a2a849a9f259e58b5752550e10e92 Mon Sep 17 00:00:00 2001 From: Stefano Chiodino Date: Thu, 5 Oct 2017 19:17:06 +0100 Subject: [PATCH 003/134] Normalises whitespace (replace tabs) and add EOF line --- .../tools/Views.Web.config.install.xdt | 70 +- build/NuSpecs/tools/Web.config.install.xdt | 793 +++++++++--------- src/Umbraco.Web.UI/Media/Web.config | 2 +- src/Umbraco.Web.UI/Views/Web.config | 98 +-- .../umbraco/Install/Views/Web.config | 96 +-- src/umbraco.MacroEngines/Resources/Web.config | 92 +- 6 files changed, 571 insertions(+), 580 deletions(-) diff --git a/build/NuSpecs/tools/Views.Web.config.install.xdt b/build/NuSpecs/tools/Views.Web.config.install.xdt index a5797232b8..4d660301a8 100644 --- a/build/NuSpecs/tools/Views.Web.config.install.xdt +++ b/build/NuSpecs/tools/Views.Web.config.install.xdt @@ -1,42 +1,32 @@ - - -
-
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/build/NuSpecs/tools/Web.config.install.xdt b/build/NuSpecs/tools/Web.config.install.xdt index 5ee5ed32c6..a381a58c3e 100644 --- a/build/NuSpecs/tools/Web.config.install.xdt +++ b/build/NuSpecs/tools/Web.config.install.xdt @@ -1,419 +1,420 @@ - - -
-
-
+ + +
+
+
- -
- - - -
-
-
-
-
- - + +
+ + + +
+
+
+
+
+ + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - + + - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - + - - - > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + - - - - - + + + + + + + + - - - - - - - - - - + + + + + - - - - - - - - + + + + + + + + + + - - - - - - - - - - - + + + + + + + + - - - - + + + + + + + + + + + - - - - - + + + + - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Umbraco.Web.UI/Media/Web.config b/src/Umbraco.Web.UI/Media/Web.config index 6cbb733ea7..cd48da3840 100644 --- a/src/Umbraco.Web.UI/Media/Web.config +++ b/src/Umbraco.Web.UI/Media/Web.config @@ -6,4 +6,4 @@ - \ No newline at end of file + diff --git a/src/Umbraco.Web.UI/Views/Web.config b/src/Umbraco.Web.UI/Views/Web.config index 479445713d..bc9ac2bdef 100644 --- a/src/Umbraco.Web.UI/Views/Web.config +++ b/src/Umbraco.Web.UI/Views/Web.config @@ -1,65 +1,65 @@ - - -
-
- - + + +
+
+ + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - + + + - - - - + + + + - - - - - - - + + + + + + - - + + - - - - - + + + + + diff --git a/src/Umbraco.Web.UI/umbraco/Install/Views/Web.config b/src/Umbraco.Web.UI/umbraco/Install/Views/Web.config index d7f2ec9848..a95df8b9d7 100644 --- a/src/Umbraco.Web.UI/umbraco/Install/Views/Web.config +++ b/src/Umbraco.Web.UI/umbraco/Install/Views/Web.config @@ -1,58 +1,58 @@ - - -
-
- - + + +
+
+ + - - - - - - - - - - - + + + + + + + + + + + - - - + + + - - - - + + + + - - - - - - - + + + + + + + - - + + - - - - - + + + + + diff --git a/src/umbraco.MacroEngines/Resources/Web.config b/src/umbraco.MacroEngines/Resources/Web.config index d96172c0e4..c98c89349d 100644 --- a/src/umbraco.MacroEngines/Resources/Web.config +++ b/src/umbraco.MacroEngines/Resources/Web.config @@ -1,56 +1,56 @@ - - -
-
- - + + +
+
+ + - - - - - - - - - + + + + + + + + + - - - + + + - - - - + + + + - - - - - - - + + + + + + + - - + + - - - - - + + + + + From 404fc40127180ff157189e50ecd245d3a735395c Mon Sep 17 00:00:00 2001 From: Marc Goodson Date: Sun, 15 Oct 2017 10:28:16 +0100 Subject: [PATCH 004/134] Skips the Macro Selection stage if only one macro exists, and it has parameters to be entered --- .../macropicker/macropicker.controller.js | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/macropicker/macropicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/macropicker/macropicker.controller.js index 69f9851926..3915282876 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/macropicker/macropicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/macropicker/macropicker.controller.js @@ -17,14 +17,17 @@ function MacroPickerController($scope, entityResource, macroResource, umbPropEdi $scope.model.selectedMacro = macro; if ($scope.wizardStep === "macroSelect") { - editParams(); + editParams(true); } else { $scope.model.submit($scope.model); } }; /** changes the view to edit the params of the selected macro */ - function editParams() { + /** if there is pnly one macro, and it has parameters - editor can skip selecting the Macro **/ + function editParams(insertIfNoParameters) { + //whether to insert the macro in the rich text editor when editParams is called and there are no parameters see U4-10537 + insertIfNoParameters = (typeof insertIfNoParameters !== 'undefined') ? insertIfNoParameters : true; //get the macro params if there are any macroResource.getMacroParameters($scope.model.selectedMacro.id) .then(function (data) { @@ -34,7 +37,11 @@ function MacroPickerController($scope, entityResource, macroResource, umbPropEdi //go to next page if there are params otherwise we can just exit if (!angular.isArray(data) || data.length === 0) { - $scope.model.submit($scope.model); + if (insertIfNoParameters) { + $scope.model.submit($scope.model); + } else { + $scope.wizardStep = 'macroSelect'; + } } else { @@ -113,12 +120,19 @@ function MacroPickerController($scope, entityResource, macroResource, umbPropEdi if (found) { //select the macro and go to next screen $scope.model.selectedMacro = found; - editParams(); + editParams(true); return; } } - //we don't have a pre-selected macro so ensure the correct step is set - $scope.wizardStep = "macroSelect"; + //if there is only one macro in the site and it has parameters, let's not make the editor choose it from a selection of one macro (unless there are no parameters - then weirdly it's a better experience to make that selection) + if ($scope.macros.length == 1) { + $scope.model.selectedMacro = $scope.macros[0]; + editParams(false); + } + else { + //we don't have a pre-selected macro so ensure the correct step is set + $scope.wizardStep = 'macroSelect'; + } }); From 0752ef06b120373ea0fea214acebf4f53a262fe0 Mon Sep 17 00:00:00 2001 From: Marc Goodson Date: Sun, 15 Oct 2017 10:36:26 +0100 Subject: [PATCH 005/134] Enables the editor to skip the macro selection stage, when there is only one Macro and it has parameters (is this a controller still used? ) --- .../common/dialogs/insertmacro.controller.js | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/insertmacro.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/insertmacro.controller.js index dbb86e87ec..1fd870b42d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/insertmacro.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/insertmacro.controller.js @@ -10,16 +10,22 @@ function InsertMacroController($scope, entityResource, macroResource, umbPropEditorHelper, macroService, formHelper) { /** changes the view to edit the params of the selected macro */ - function editParams() { + /** if there is pnly one macro, and it has parameters - editor can skip selecting the Macro **/ + function editParams(insertIfNoParameters) { + //whether to insert the macro in the rich text editor when editParams is called and there are no parameters see U4-10537 + insertIfNoParameters = (typeof insertIfNoParameters !== 'undefined') ? insertIfNoParameters : true; //get the macro params if there are any macroResource.getMacroParameters($scope.selectedMacro.id) .then(function (data) { //go to next page if there are params otherwise we can just exit if (!angular.isArray(data) || data.length === 0) { - //we can just exist! - submitForm(); - + //we can just exist! + if (insertIfNoParameters) { + submitForm(); + } else { + $scope.wizardStep = 'macroSelect'; + } } else { $scope.wizardStep = "paramSelect"; $scope.macroParams = data; @@ -117,7 +123,7 @@ function InsertMacroController($scope, entityResource, macroResource, umbPropEdi formHelper.resetForm({ scope: $scope }); if ($scope.wizardStep === "macroSelect") { - editParams(); + editParams(true); } else { submitForm(); @@ -155,12 +161,19 @@ function InsertMacroController($scope, entityResource, macroResource, umbPropEdi if (found) { //select the macro and go to next screen $scope.selectedMacro = found; - editParams(); + editParams(true); return; } } - //we don't have a pre-selected macro so ensure the correct step is set - $scope.wizardStep = "macroSelect"; + //if there is only one macro in the site and it has parameters, let's not make the editor choose it from a selection of one macro (unless there are no parameters - then weirdly it's a better experience to make that selection) + if ($scope.macros.length == 1) { + $scope.selectedMacro = $scope.macros[0]; + editParams(false); + } + else { + //we don't have a pre-selected macro so ensure the correct step is set + $scope.wizardStep = 'macroSelect'; + } }); From 899265c5c54d913f7b505c0614089a5f039bad00 Mon Sep 17 00:00:00 2001 From: Andy Felton Date: Sat, 21 Oct 2017 14:44:09 +0100 Subject: [PATCH 006/134] Use the underlying Peta Poco DB type to get the Type --- src/Umbraco.Core/DatabaseContext.cs | 34 ++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs index 1409016da6..b78d35a17f 100644 --- a/src/Umbraco.Core/DatabaseContext.cs +++ b/src/Umbraco.Core/DatabaseContext.cs @@ -279,16 +279,34 @@ namespace Umbraco.Core { get { - string dbtype = Database.Connection == null ? ProviderName : Database.Connection.GetType().Name; + if (Database.Connection == null) + { + string dbtype = ProviderName; - if (dbtype.StartsWith("MySql")) return DatabaseProviders.MySql; - if (dbtype.StartsWith("SqlCe") || dbtype.Contains("SqlServerCe")) return DatabaseProviders.SqlServerCE; - if (dbtype.StartsWith("Npgsql")) return DatabaseProviders.PostgreSQL; - if (dbtype.StartsWith("Oracle") || dbtype.Contains("OracleClient")) return DatabaseProviders.Oracle; - if (dbtype.StartsWith("SQLite")) return DatabaseProviders.SQLite; - if (dbtype.Contains("Azure")) return DatabaseProviders.SqlAzure; + if (dbtype.StartsWith("MySql")) return DatabaseProviders.MySql; + if (dbtype.StartsWith("SqlCe") || dbtype.Contains("SqlServerCe")) return DatabaseProviders.SqlServerCE; + if (dbtype.StartsWith("Npgsql")) return DatabaseProviders.PostgreSQL; + if (dbtype.StartsWith("Oracle") || dbtype.Contains("OracleClient")) return DatabaseProviders.Oracle; + if (dbtype.StartsWith("SQLite")) return DatabaseProviders.SQLite; + if (dbtype.Contains("Azure")) return DatabaseProviders.SqlAzure; - return DatabaseProviders.SqlServer; + return DatabaseProviders.SqlServer; + } + else + { + Database.DBType dbType = Database.DatabaseType; + + switch (dbType) + { + case Persistence.Database.DBType.SqlServer: return DatabaseProviders.SqlServer; + case Persistence.Database.DBType.SqlServerCE: return DatabaseProviders.SqlServerCE; + case Persistence.Database.DBType.MySql: return DatabaseProviders.MySql; + case Persistence.Database.DBType.PostgreSQL: return DatabaseProviders.PostgreSQL; + case Persistence.Database.DBType.Oracle: return DatabaseProviders.Oracle; + case Persistence.Database.DBType.SQLite: return DatabaseProviders.SQLite; + default: return (ProviderName.Contains("Azure"))? DatabaseProviders.SqlAzure : DatabaseProviders.SqlServer; + } + } } } From 802a4386c362b2efb764d3a6d76490c0ff80930e Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 2 Nov 2017 10:58:44 +0000 Subject: [PATCH 007/134] Renames the true false field to be more descriptive, adds migration to change existing name. --- .../Migrations/Initial/BaseDataCreation.cs | 12 ++++++------ src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../PropertyEditors/TrueFalsePropertyEditor.cs | 2 +- src/umbraco.editorControls/yesno/YesNoDataType.cs | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs index 1f94d30b0f..2c46b031e7 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs @@ -122,7 +122,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -88, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-88", SortOrder = 32, UniqueId = new Guid("0cc0eba1-9960-42c9-bf9b-60e150b429ae"), Text = "Textstring", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -87, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-87", SortOrder = 4, UniqueId = new Guid("ca90c950-0aff-4e72-b976-a30b1ac57dad"), Text = "Richtext editor", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -51, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-51", SortOrder = 2, UniqueId = new Guid("2e6d3631-066e-44b8-aec4-96f09099b2b5"), Text = "Numeric", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -49, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-49", SortOrder = 2, UniqueId = new Guid("92897bc6-a5f3-4ffe-ae27-f2e7e33dda49"), Text = "True/false", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); + _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -49, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-49", SortOrder = 2, UniqueId = new Guid("92897bc6-a5f3-4ffe-ae27-f2e7e33dda49"), Text = "Single Checkbox", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -43, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-43", SortOrder = 2, UniqueId = new Guid("fbaf13a8-4036-41f2-93a3-974f678c312a"), Text = "Checkbox list", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -42, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-42", SortOrder = 2, UniqueId = new Guid("0b6a45e7-44ba-430d-9da5-4e46060b9e03"), Text = "Dropdown", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = new Guid("5046194e-4237-453c-a547-15db3a07c4e1"), Text = "Date Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); @@ -188,18 +188,18 @@ namespace Umbraco.Core.Persistence.Migrations.Initial private void CreateUmbracoUserGroup2AppData() { _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Content }); - _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Developer }); + _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Developer }); _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Media }); _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 = 2, AppAlias = Constants.Applications.Content }); + _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.Forms }); + _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.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 585b9c8682..b16ad46e48 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -545,6 +545,7 @@ + diff --git a/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs index 0dc181cbc3..d63bdb9af7 100644 --- a/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs @@ -3,7 +3,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.TrueFalseAlias, "True/False", PropertyEditorValueTypes.Integer, "boolean", IsParameterEditor = true, Group = "Common", Icon="icon-checkbox")] + [PropertyEditor(Constants.PropertyEditors.TrueFalseAlias, "Single Checkbox", PropertyEditorValueTypes.Integer, "boolean", IsParameterEditor = true, Group = "Common", Icon="icon-checkbox")] public class TrueFalsePropertyEditor : PropertyEditor { protected override PreValueEditor CreatePreValueEditor() diff --git a/src/umbraco.editorControls/yesno/YesNoDataType.cs b/src/umbraco.editorControls/yesno/YesNoDataType.cs index 699af1a364..3e949d1878 100644 --- a/src/umbraco.editorControls/yesno/YesNoDataType.cs +++ b/src/umbraco.editorControls/yesno/YesNoDataType.cs @@ -35,7 +35,7 @@ namespace umbraco.editorControls.yesno public override string DataTypeName { - get {return "True/False (Ja/Nej)";} + get {return "Single Checkbox";} } public override Guid Id { From a861d306c96cb3353227523313d5067bef5134ba Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 7 Nov 2017 09:39:18 +0000 Subject: [PATCH 008/134] Makes changes recommended by Sebastian, includes missing Migration. --- .../Migrations/Initial/BaseDataCreation.cs | 2 +- .../RenameTrueFalseField.cs | 28 +++++++++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 2 +- .../TrueFalsePropertyEditor.cs | 2 +- .../yesno/YesNoDataType.cs | 2 +- 5 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenEightZero/RenameTrueFalseField.cs diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs index 2c46b031e7..f0a9d80593 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs @@ -122,7 +122,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -88, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-88", SortOrder = 32, UniqueId = new Guid("0cc0eba1-9960-42c9-bf9b-60e150b429ae"), Text = "Textstring", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -87, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-87", SortOrder = 4, UniqueId = new Guid("ca90c950-0aff-4e72-b976-a30b1ac57dad"), Text = "Richtext editor", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -51, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-51", SortOrder = 2, UniqueId = new Guid("2e6d3631-066e-44b8-aec4-96f09099b2b5"), Text = "Numeric", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -49, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-49", SortOrder = 2, UniqueId = new Guid("92897bc6-a5f3-4ffe-ae27-f2e7e33dda49"), Text = "Single Checkbox", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); + _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -49, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-49", SortOrder = 2, UniqueId = new Guid("92897bc6-a5f3-4ffe-ae27-f2e7e33dda49"), Text = "Checkbox", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -43, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-43", SortOrder = 2, UniqueId = new Guid("fbaf13a8-4036-41f2-93a3-974f678c312a"), Text = "Checkbox list", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -42, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-42", SortOrder = 2, UniqueId = new Guid("0b6a45e7-44ba-430d-9da5-4e46060b9e03"), Text = "Dropdown", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = new Guid("5046194e-4237-453c-a547-15db3a07c4e1"), Text = "Date Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenEightZero/RenameTrueFalseField.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenEightZero/RenameTrueFalseField.cs new file mode 100644 index 0000000000..b425086502 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenEightZero/RenameTrueFalseField.cs @@ -0,0 +1,28 @@ +using System.Data; +using System.Linq; +using Umbraco.Core.Configuration; +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenEightZero +{ + [MigrationAttribute("7.8.0", 0, Constants.System.UmbracoMigrationName)] + public class RenameTrueFalseField : MigrationBase + { + public RenameTrueFalseField(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger) + { + } + + public override void Up() + { + //rename the existing true/false field + Update.Table("umbracoNode").Set(new { text = "Checkbox" }).Where(new { id = -49 }); + } + + public override void Down() + { + //set the field back to true/false + Update.Table("umbracoNode").Set(new { text = "True/false" }).Where(new { id = -49 }); + } + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index b16ad46e48..12648df9d3 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -545,7 +545,7 @@ - + diff --git a/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs index d63bdb9af7..6a8e726911 100644 --- a/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TrueFalsePropertyEditor.cs @@ -3,7 +3,7 @@ using Umbraco.Core.PropertyEditors; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.TrueFalseAlias, "Single Checkbox", PropertyEditorValueTypes.Integer, "boolean", IsParameterEditor = true, Group = "Common", Icon="icon-checkbox")] + [PropertyEditor(Constants.PropertyEditors.TrueFalseAlias, "Checkbox", PropertyEditorValueTypes.Integer, "boolean", IsParameterEditor = true, Group = "Common", Icon="icon-checkbox")] public class TrueFalsePropertyEditor : PropertyEditor { protected override PreValueEditor CreatePreValueEditor() diff --git a/src/umbraco.editorControls/yesno/YesNoDataType.cs b/src/umbraco.editorControls/yesno/YesNoDataType.cs index 3e949d1878..ee9d9d84bf 100644 --- a/src/umbraco.editorControls/yesno/YesNoDataType.cs +++ b/src/umbraco.editorControls/yesno/YesNoDataType.cs @@ -35,7 +35,7 @@ namespace umbraco.editorControls.yesno public override string DataTypeName { - get {return "Single Checkbox";} + get {return "Checkbox";} } public override Guid Id { From a388657dbbc1a494b5be9ce9a81f54755abfbd30 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Wed, 15 Nov 2017 19:11:35 +0100 Subject: [PATCH 009/134] Change types of listview properties --- .../PropertyEditors/ListViewPropertyEditor.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs index 2ee208ed48..3a0066f9fc 100644 --- a/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ListViewPropertyEditor.cs @@ -37,14 +37,16 @@ namespace Umbraco.Web.PropertyEditors new {name = "Grid", path = "views/propertyeditors/listview/layouts/grid/grid.html", icon = "icon-thumbnails-small", isSystem = 1, selected = true} } }, - {"bulkActionPermissions", new + { + "bulkActionPermissions", new { allowBulkPublish = true, allowBulkUnpublish = true, allowBulkCopy = true, allowBulkMove = false, allowBulkDelete = true - }} + } + } }; } } @@ -52,7 +54,7 @@ namespace Umbraco.Web.PropertyEditors internal class ListViewPreValueEditor : PreValueEditor { [PreValueField("tabName", "Tab Name", "textstring", Description = "The name of the listview tab (default if empty: 'Child Items')")] - public int TabName { get; set; } + public string TabName { get; set; } [PreValueField("displayAtTabNumber", "Display At Tab Number", "number", Description = "Which tab position that the list of child items will be displayed")] public int DisplayAtTabNumber { get; set; } @@ -61,7 +63,7 @@ namespace Umbraco.Web.PropertyEditors public int PageSize { get; set; } [PreValueField("layouts", "Layouts", "views/propertyeditors/listview/layouts.prevalues.html")] - public int Layouts { get; set; } + public object Layouts { get; set; } [PreValueField("includeProperties", "Columns Displayed", "views/propertyeditors/listview/includeproperties.prevalues.html", Description = "The properties that will be displayed for each column")] @@ -69,10 +71,10 @@ namespace Umbraco.Web.PropertyEditors [PreValueField("orderBy", "Order By", "views/propertyeditors/listview/sortby.prevalues.html", Description = "The default sort order for the list")] - public int OrderBy { get; set; } + public string OrderBy { get; set; } [PreValueField("orderDirection", "Order Direction", "views/propertyeditors/listview/orderdirection.prevalues.html")] - public int OrderDirection { get; set; } + public string OrderDirection { get; set; } [PreValueField("bulkActionPermissions", "Bulk Action Permissions", "views/propertyeditors/listview/bulkactionpermissions.prevalues.html", Description = "The bulk actions that are allowed from the list view")] From 3d326158ca0a465950bde0a1cacff3021a774024 Mon Sep 17 00:00:00 2001 From: Matt Darby Date: Wed, 6 Dec 2017 19:58:58 +0700 Subject: [PATCH 010/134] Check node permissions only on content list view --- .../listview/listview.controller.js | 37 ++++++++++--------- .../propertyeditors/listview/listview.html | 2 +- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js index 8f9279fb02..03b95b6883 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js @@ -57,24 +57,27 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie totalPages: 0, items: [] }; + + //when this is null, we don't check permissions + $scope.currentNodePermissions = null; + + if ($scope.entityType === "content") { + //Just ensure we do have an editorState + if (editorState.current) { + //Fetch current node allowed actions for the current user + //This is the current node & not each individual child node in the list + var currentUserPermissions = editorState.current.allowedActions; - $scope.currentNodePermissions = {} - - //Just ensure we do have an editorState - if (editorState.current) { - //Fetch current node allowed actions for the current user - //This is the current node & not each individual child node in the list - var currentUserPermissions = editorState.current.allowedActions; - - //Create a nicer model rather than the funky & hard to remember permissions strings - $scope.currentNodePermissions = { - "canCopy": _.contains(currentUserPermissions, 'O'), //Magic Char = O - "canCreate": _.contains(currentUserPermissions, 'C'), //Magic Char = C - "canDelete": _.contains(currentUserPermissions, 'D'), //Magic Char = D - "canMove": _.contains(currentUserPermissions, 'M'), //Magic Char = M - "canPublish": _.contains(currentUserPermissions, 'U'), //Magic Char = U - "canUnpublish": _.contains(currentUserPermissions, 'U'), //Magic Char = Z (however UI says it can't be set, so if we can publish 'U' we can unpublish) - }; + //Create a nicer model rather than the funky & hard to remember permissions strings + $scope.currentNodePermissions = { + "canCopy": _.contains(currentUserPermissions, 'O'), //Magic Char = O + "canCreate": _.contains(currentUserPermissions, 'C'), //Magic Char = C + "canDelete": _.contains(currentUserPermissions, 'D'), //Magic Char = D + "canMove": _.contains(currentUserPermissions, 'M'), //Magic Char = M + "canPublish": _.contains(currentUserPermissions, 'U'), //Magic Char = U + "canUnpublish": _.contains(currentUserPermissions, 'U'), //Magic Char = Z (however UI says it can't be set, so if we can publish 'U' we can unpublish) + }; + } } //when this is null, we don't check permissions diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html index 97500fd7c1..2683317dc1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html @@ -10,7 +10,7 @@ - +
Create From 4babcbf96e7d4fb42c5b7eef98159bb265f54c11 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sat, 17 Mar 2018 17:16:14 +0100 Subject: [PATCH 011/134] Hide tooltip of slider property editor in document type editor property preview --- .../src/less/property-editors.less | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 2d317fa4a0..c2eaca05fc 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -879,7 +879,21 @@ ul.color-picker li a { // // Nested boolean (e.g. list view bulk action permissions) -// ---------------------=====----------------------------- +// ------------------------------------------------------- .umb-nested-boolean label {margin-bottom: 8px; float: left; width: 320px;} .umb-nested-boolean label span {float: left; width: 80%;} .umb-nested-boolean label input[type='checkbox'] {margin-right: 10px; float: left;} + + +// +// Custom styles of property editors in property preview in document type editor +// ----------------------------------------------------------------------------- +.umb-group-builder__property-preview { + .umb-property-editor { + .slider { + .tooltip { + display: none; + } + } + } +} From 587d9b6d6c09abaeaea2da53dc0c7af13dd8b86a Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sun, 18 Mar 2018 20:05:16 +0100 Subject: [PATCH 012/134] Remove umb-pane from dialog --- .../src/views/datatypes/move.html | 2 +- .../src/views/documenttypes/copy.html | 2 +- .../src/views/documenttypes/move.html | 2 +- .../src/views/media/move.html | 91 +++++++++---------- .../src/views/mediatypes/copy.html | 2 +- .../src/views/mediatypes/move.html | 2 +- 6 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/move.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/move.html index 09390cdb81..f05b8a6c79 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/move.html @@ -1,4 +1,4 @@ -
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html index db1a0db640..2976f65917 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html @@ -1,4 +1,4 @@ -
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html index c982abc0c0..1ed224b5ba 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html @@ -1,4 +1,4 @@ -
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/media/move.html b/src/Umbraco.Web.UI.Client/src/views/media/move.html index d04d66f706..b37b71b639 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/media/move.html @@ -1,56 +1,55 @@
- diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html index 319e59c4cc..fcc26b9928 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html @@ -1,4 +1,4 @@ -
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html index 59172eb547..18f7aee337 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html @@ -1,4 +1,4 @@ -
+
From 73565d9be1476b5de46f37b420e20da8c0371d25 Mon Sep 17 00:00:00 2001 From: Marc Goodson Date: Thu, 29 Mar 2018 09:12:57 +0100 Subject: [PATCH 013/134] Consider the 'case' of the Member Group/Role Name when comparing, during assignment, whether or not the Member Group/Role exists and whether it needs to be created... and whether the Member belongs to a particular Group/Role and whether they need to be assigned. --- .../Persistence/Repositories/MemberGroupRepository.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs index 4006ea26c9..404c32640a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs @@ -242,7 +242,7 @@ namespace Umbraco.Core.Persistence.Repositories .Where(dto => dto.NodeObjectType == NodeObjectTypeId) .Where("umbracoNode." + SqlSyntax.GetQuotedColumnName("text") + " in (@names)", new { names = roleNames }); var existingRoles = Database.Fetch(existingSql).Select(x => x.Text); - var missingRoles = roleNames.Except(existingRoles); + var missingRoles = roleNames.Except(existingRoles, StringComparer.CurrentCultureIgnoreCase); var missingGroups = missingRoles.Select(x => new MemberGroup {Name = x}).ToArray(); if (UnitOfWork.Events.DispatchCancelable(SavingMemberGroup, this, new SaveEventArgs(missingGroups))) @@ -280,8 +280,8 @@ namespace Umbraco.Core.Persistence.Repositories //exist in the roleNames list, then determine which ones are not currently assigned. var mId = memberId; var found = currentlyAssigned.Where(x => x.MemberId == mId).ToArray(); - var assignedRoles = found.Where(x => roleNames.Contains(x.RoleName)).Select(x => x.RoleName); - var nonAssignedRoles = roleNames.Except(assignedRoles); + var assignedRoles = found.Where(x => roleNames.Contains(x.RoleName,StringComparer.CurrentCultureIgnoreCase)).Select(x => x.RoleName); + var nonAssignedRoles = roleNames.Except(assignedRoles, StringComparer.CurrentCultureIgnoreCase); foreach (var toAssign in nonAssignedRoles) { var groupId = rolesForNames.First(x => x.Text == toAssign).NodeId; From deaf26109b970da33a034d24e0603a273cf8518f Mon Sep 17 00:00:00 2001 From: Poornima Nayar Date: Tue, 15 May 2018 19:33:36 +0100 Subject: [PATCH 014/134] check for recursive value --- src/Umbraco.Web/umbraco.presentation/item.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/item.cs b/src/Umbraco.Web/umbraco.presentation/item.cs index 1edc6cca17..33150d6187 100644 --- a/src/Umbraco.Web/umbraco.presentation/item.cs +++ b/src/Umbraco.Web/umbraco.presentation/item.cs @@ -66,8 +66,12 @@ namespace umbraco if (publishedContent == null) { - var recursiveVal = GetRecursiveValueLegacy(elements); - _fieldContent = recursiveVal.IsNullOrWhiteSpace() ? _fieldContent : recursiveVal; + if (recursive) + { + var recursiveVal = GetRecursiveValueLegacy(elements); + _fieldContent = recursiveVal.IsNullOrWhiteSpace() ? _fieldContent : recursiveVal; + } + } //check for published content and get its value using that @@ -222,4 +226,4 @@ namespace umbraco } } } -} \ No newline at end of file +} From e26b8ae6d949f41ed1a8edfa697044472b177139 Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Thu, 31 May 2018 22:03:12 +0100 Subject: [PATCH 015/134] Migrated Examine Management controller --- .../Editors/BackOfficeServerVariables.cs | 2 +- .../Editors/ExamineManagementController.cs | 321 ++++++++++++++++++ src/Umbraco.Web/Umbraco.Web.csproj | 1 + src/Umbraco.Web/UrlHelperExtensions.cs | 4 +- .../ExamineManagementApiController.cs | 256 +------------- 5 files changed, 328 insertions(+), 256 deletions(-) create mode 100644 src/Umbraco.Web/Editors/ExamineManagementController.cs diff --git a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs index 870bb4f3f7..196823701a 100644 --- a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs +++ b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs @@ -254,7 +254,7 @@ namespace Umbraco.Web.Editors controller => controller.GetTags("")) }, { - "examineMgmtBaseUrl", _urlHelper.GetUmbracoApiServiceBaseUrl( + "examineMgmtBaseUrl", _urlHelper.GetUmbracoApiServiceBaseUrl( controller => controller.GetIndexerDetails()) }, { diff --git a/src/Umbraco.Web/Editors/ExamineManagementController.cs b/src/Umbraco.Web/Editors/ExamineManagementController.cs new file mode 100644 index 0000000000..c4ef00eff8 --- /dev/null +++ b/src/Umbraco.Web/Editors/ExamineManagementController.cs @@ -0,0 +1,321 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Reflection; +using System.Web.Http; +using Examine; +using Examine.LuceneEngine; +using Examine.LuceneEngine.Providers; +using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Composing; +using Umbraco.Core.Logging; +using Umbraco.Web.Mvc; +using Umbraco.Web.Search; + +namespace Umbraco.Web.Editors +{ + [PluginController("UmbracoApi")] + public class ExamineManagementController : UmbracoAuthorizedJsonController + { + private readonly IExamineManager _examineManager; + private readonly ILogger _logger; + private readonly IRuntimeCacheProvider _runtimeCacheProvider; + + public ExamineManagementController(IExamineManager examineManager, ILogger logger, + IRuntimeCacheProvider runtimeCacheProvider) + { + _examineManager = examineManager; + _logger = logger; + _runtimeCacheProvider = runtimeCacheProvider; + } + + /// + /// Get the details for indexers + /// + /// + public IEnumerable GetIndexerDetails() + { + return _examineManager.IndexProviders.Select(CreateModel).OrderBy(x => + { + //order by name , but strip the "Indexer" from the end if it exists + return x.Name.TrimEnd("Indexer"); + }); + } + + /// + /// Get the details for searchers + /// + /// + public IEnumerable GetSearcherDetails() + { + var model = new List( + _examineManager.IndexProviders.Select(indexer => + { + var searcher = indexer.Value.GetSearcher(); + var searcherName = (searcher as BaseLuceneSearcher)?.Name ?? string.Concat(indexer.Key, "Searcher"); + + var indexerModel = new ExamineSearcherModel + { + Name = searcherName + }; + var props = TypeHelper.CachedDiscoverableProperties(searcher.GetType(), mustWrite: false) + //ignore these properties + .Where(x => new[] { "Description" }.InvariantContains(x.Name) == false) + .Where(x => x.GetCustomAttribute() + ?.State != EditorBrowsableState.Never) + .OrderBy(x => x.Name); + foreach (var p in props) + { + indexerModel.ProviderProperties.Add(p.Name, p.GetValue(searcher, null)?.ToString()); + } + + return indexerModel; + }).OrderBy(x => + { + //order by name , but strip the "Searcher" from the end if it exists + return x.Name.TrimEnd("Searcher"); + })); + return model; + } + + public ISearchResults GetSearchResults(string searcherName, string query, string queryType) + { + if (queryType == null) + { + throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); + } + + if (query.IsNullOrWhiteSpace()) + { + return LuceneSearchResults.Empty(); + } + + var msg = ValidateLuceneSearcher(searcherName, out var searcher); + if (msg.IsSuccessStatusCode) + { + if (queryType.InvariantEquals("text")) + { + return searcher.Search(query, false); + } + + if (queryType.InvariantEquals("lucene")) + { + return searcher.Search(searcher.CreateCriteria().RawQuery(query)); + } + + throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); + } + + throw new HttpResponseException(msg); + } + + /// + /// Check if the index has been rebuilt + /// + /// + /// + /// + /// This is kind of rudimentary since there's no way we can know that the index has rebuilt, we + /// have a listener for the index op complete so we'll just check if that key is no longer there in the runtime cache + /// + public ExamineIndexerModel PostCheckRebuildIndex(string indexerName) + { + var msg = ValidateLuceneIndexer(indexerName, out LuceneIndexer indexer); + if (msg.IsSuccessStatusCode) + { + var cacheKey = "temp_indexing_op_" + indexerName; + var found = ApplicationCache.RuntimeCache.GetCacheItem(cacheKey); + + //if its still there then it's not done + return found != null + ? null + : CreateModel(new KeyValuePair(indexerName, indexer)); + } + + throw new HttpResponseException(msg); + } + + /// + /// Rebuilds the index + /// + /// + /// + public HttpResponseMessage PostRebuildIndex(string indexerName) + { + var msg = ValidateLuceneIndexer(indexerName, out LuceneIndexer indexer); + if (msg.IsSuccessStatusCode) + { + _logger.Info($"Rebuilding index '{indexerName}'"); + + //remove it in case there's a handler there alraedy + indexer.IndexOperationComplete -= Indexer_IndexOperationComplete; + + //now add a single handler + indexer.IndexOperationComplete += Indexer_IndexOperationComplete; + + var cacheKey = "temp_indexing_op_" + indexer.Name; + + //put temp val in cache which is used as a rudimentary way to know when the indexing is done + ApplicationCache.RuntimeCache.InsertCacheItem(cacheKey, () => "tempValue", TimeSpan.FromMinutes(5), + false); + + try + { + indexer.RebuildIndex(); + } + catch (Exception ex) + { + //ensure it's not listening + indexer.IndexOperationComplete -= Indexer_IndexOperationComplete; + Logger.Error("An error occurred rebuilding index", ex); + var response = Request.CreateResponse(HttpStatusCode.Conflict); + response.Content = + new + StringContent($"The index could not be rebuilt at this time, most likely there is another thread currently writing to the index. Error: {ex}"); + response.ReasonPhrase = "Could Not Rebuild"; + return response; + } + } + + return msg; + } + + private ExamineIndexerModel CreateModel(KeyValuePair indexerKeyVal) + { + var indexer = indexerKeyVal.Value; + var indexName = indexerKeyVal.Key; + var indexerModel = new ExamineIndexerModel + { + FieldDefinitions = indexer.FieldDefinitionCollection, + Name = indexName + }; + + var props = TypeHelper.CachedDiscoverableProperties(indexer.GetType(), mustWrite: false) + //ignore these properties + .Where(x => new[] { "IndexerData", "Description", "WorkingFolder" } + .InvariantContains(x.Name) == false) + .OrderBy(x => x.Name); + + foreach (var p in props) + { + var val = p.GetValue(indexer, null); + if (val == null) + { + // Do not warn for new new attribute that is optional + if (string.Equals(p.Name, "DirectoryFactory", StringComparison.InvariantCultureIgnoreCase) == false) + { + Logger + .Warn("Property value was null when setting up property on indexer: " + indexName + + " property: " + p.Name); + } + + val = string.Empty; + } + + indexerModel.ProviderProperties.Add(p.Name, val.ToString()); + } + + if (indexer is LuceneIndexer luceneIndexer) + { + indexerModel.IsLuceneIndex = true; + + if (luceneIndexer.IndexExists()) + { + indexerModel.IsHealthy = luceneIndexer.IsHealthy(out var indexError); + + if (indexerModel.IsHealthy == false) + { + //we cannot continue at this point + indexerModel.Error = indexError.ToString(); + return indexerModel; + } + + indexerModel.DocumentCount = luceneIndexer.GetIndexDocumentCount(); + indexerModel.FieldCount = luceneIndexer.GetIndexFieldCount(); + } + else + { + indexerModel.DocumentCount = 0; + indexerModel.FieldCount = 0; + } + } + + return indexerModel; + } + + private HttpResponseMessage ValidateLuceneSearcher(string searcherName, out LuceneSearcher searcher) + { + foreach (var indexer in _examineManager.IndexProviders) + { + var s = indexer.Value.GetSearcher(); + var sName = (s as BaseLuceneSearcher)?.Name ?? string.Concat(indexer.Key, "Searcher"); + if (sName != searcherName) + { + continue; + } + + searcher = s as LuceneSearcher; + + //Found it, return OK + if (searcher != null) + { + return Request.CreateResponse(HttpStatusCode.OK); + } + + //Return an error since it's not the right type + var response = Request.CreateResponse(HttpStatusCode.BadRequest); + response.Content = + new StringContent($"The searcher {searcherName} is not of type {typeof(LuceneSearcher)}"); + response.ReasonPhrase = "Wrong Searcher Type"; + return response; + } + + searcher = null; + + var response1 = Request.CreateResponse(HttpStatusCode.BadRequest); + response1.Content = new StringContent($"No searcher found with name = {searcherName}"); + response1.ReasonPhrase = "Searcher Not Found"; + return response1; + } + + private HttpResponseMessage ValidateLuceneIndexer(string indexerName, out T indexer) + where T : class, IIndexer + { + indexer = null; + + if (_examineManager.IndexProviders.ContainsKey(indexerName) + && _examineManager.IndexProviders[indexerName] is T casted) + { + //return Ok! + indexer = casted; + return Request.CreateResponse(HttpStatusCode.OK); + } + + var response = Request.CreateResponse(HttpStatusCode.BadRequest); + response.Content = new StringContent($"No indexer found with name = {indexerName} of type {typeof(T)}"); + response.ReasonPhrase = "Indexer Not Found"; + return response; + } + + //static listener so it's not GC'd + private void Indexer_IndexOperationComplete(object sender, EventArgs e) + { + var indexer = (LuceneIndexer) sender; + + //ensure it's not listening anymore + indexer.IndexOperationComplete -= Indexer_IndexOperationComplete; + + _logger + .Info($"Rebuilding index '{indexer.Name}' done, {indexer.CommitCount} items committed (can differ from the number of items in the index)"); + + var cacheKey = "temp_indexing_op_" + indexer.Name; + _runtimeCacheProvider.ClearCacheItem(cacheKey); + } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 537be3fbfa..5281b307aa 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -121,6 +121,7 @@ + diff --git a/src/Umbraco.Web/UrlHelperExtensions.cs b/src/Umbraco.Web/UrlHelperExtensions.cs index f1363f090a..98856119c1 100644 --- a/src/Umbraco.Web/UrlHelperExtensions.cs +++ b/src/Umbraco.Web/UrlHelperExtensions.cs @@ -10,6 +10,7 @@ using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Exceptions; using Umbraco.Web.Composing; +using Umbraco.Web.Editors; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi; using Umbraco.Web.WebServices; @@ -28,7 +29,8 @@ namespace Umbraco.Web /// public static string GetExamineManagementServicePath(this UrlHelper url) { - var result = url.GetUmbracoApiService("GetIndexerDetails"); + // TODO: Possibly remove this method, I think it's unused... + var result = url.GetUmbracoApiService("GetIndexerDetails"); return result.TrimEnd("GetIndexerDetails").EnsureEndsWith('/'); } diff --git a/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs b/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs index 34ffd1426b..193e47c720 100644 --- a/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs +++ b/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs @@ -23,7 +23,8 @@ using Umbraco.Web.WebApi.Filters; namespace Umbraco.Web.WebServices { - [ValidateAngularAntiForgeryToken] + [ValidateAngularAntiForgeryToken] + [Obsolete] public class ExamineManagementApiController : UmbracoAuthorizedApiController { public ExamineManagementApiController(IExamineManager examineManager, ILogger logger, IRuntimeCacheProvider runtimeCacheProvider) @@ -81,258 +82,5 @@ namespace Umbraco.Web.WebServices var totalIndexed = searcher.Search(criteria); return total == totalIndexed.TotalItemCount; } - - /// - /// Get the details for indexers - /// - /// - public IEnumerable GetIndexerDetails() - { - return _examineManager.IndexProviders.Select(CreateModel).OrderBy(x => - { - //order by name , but strip the "Indexer" from the end if it exists - return x.Name.TrimEnd("Indexer"); - }); - } - - /// - /// Get the details for searchers - /// - /// - public IEnumerable GetSearcherDetails() - { - var model = new List( - _examineManager.IndexProviders.Select(indexer => - { - var searcher = indexer.Value.GetSearcher(); - var searcherName = (searcher as BaseLuceneSearcher)?.Name ?? string.Concat(indexer.Key, "Searcher"); - - var indexerModel = new ExamineSearcherModel() - { - Name = searcherName - }; - var props = TypeHelper.CachedDiscoverableProperties(searcher.GetType(), mustWrite: false) - //ignore these properties - .Where(x => new[] {"Description"}.InvariantContains(x.Name) == false) - .Where(x => x.GetCustomAttribute()?.State != EditorBrowsableState.Never) - .OrderBy(x => x.Name); - foreach (var p in props) - { - indexerModel.ProviderProperties.Add(p.Name, p.GetValue(searcher, null)?.ToString()); - } - return indexerModel; - }).OrderBy(x => - { - //order by name , but strip the "Searcher" from the end if it exists - return x.Name.TrimEnd("Searcher"); - })); - return model; - } - - public ISearchResults GetSearchResults(string searcherName, string query, string queryType) - { - if (queryType == null) - { - throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); - } - - - if (query.IsNullOrWhiteSpace()) - return LuceneSearchResults.Empty(); - - var msg = ValidateLuceneSearcher(searcherName, out var searcher); - if (msg.IsSuccessStatusCode) - { - if (queryType.InvariantEquals("text")) - { - return searcher.Search(query, false); - } - if (queryType.InvariantEquals("lucene")) - { - return searcher.Search(searcher.CreateCriteria().RawQuery(query)); - } - throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); - } - throw new HttpResponseException(msg); - } - - /// - /// Rebuilds the index - /// - /// - /// - public HttpResponseMessage PostRebuildIndex(string indexerName) - { - var msg = ValidateLuceneIndexer(indexerName, out LuceneIndexer indexer); - if (msg.IsSuccessStatusCode) - { - _logger.Info($"Rebuilding index '{indexerName}'"); - - //remove it in case there's a handler there alraedy - indexer.IndexOperationComplete -= Indexer_IndexOperationComplete; - //now add a single handler - indexer.IndexOperationComplete += Indexer_IndexOperationComplete; - - var cacheKey = "temp_indexing_op_" + indexer.Name; - //put temp val in cache which is used as a rudimentary way to know when the indexing is done - ApplicationCache.RuntimeCache.InsertCacheItem(cacheKey, () => "tempValue", TimeSpan.FromMinutes(5), isSliding: false); - - try - { - indexer.RebuildIndex(); - } - catch (Exception ex) - { - //ensure it's not listening - indexer.IndexOperationComplete -= Indexer_IndexOperationComplete; - Logger.Error("An error occurred rebuilding index", ex); - var response = Request.CreateResponse(HttpStatusCode.Conflict); - response.Content = new StringContent($"The index could not be rebuilt at this time, most likely there is another thread currently writing to the index. Error: {ex}"); - response.ReasonPhrase = "Could Not Rebuild"; - return response; - } - } - return msg; - } - - //static listener so it's not GC'd - private void Indexer_IndexOperationComplete(object sender, EventArgs e) - { - var indexer = (LuceneIndexer) sender; - - //ensure it's not listening anymore - indexer.IndexOperationComplete -= Indexer_IndexOperationComplete; - - _logger.Info($"Rebuilding index '{indexer.Name}' done, {indexer.CommitCount} items committed (can differ from the number of items in the index)"); - - var cacheKey = "temp_indexing_op_" + indexer.Name; - _runtimeCacheProvider.ClearCacheItem(cacheKey); - } - - /// - /// Check if the index has been rebuilt - /// - /// - /// - /// - /// This is kind of rudimentary since there's no way we can know that the index has rebuilt, we - /// have a listener for the index op complete so we'll just check if that key is no longer there in the runtime cache - /// - public ExamineIndexerModel PostCheckRebuildIndex(string indexerName) - { - var msg = ValidateLuceneIndexer(indexerName, out LuceneIndexer indexer); - if (msg.IsSuccessStatusCode) - { - var cacheKey = "temp_indexing_op_" + indexerName; - var found = ApplicationCache.RuntimeCache.GetCacheItem(cacheKey); - //if its still there then it's not done - return found != null - ? null - : CreateModel(new KeyValuePair(indexerName, indexer)); - } - throw new HttpResponseException(msg); - } - - private ExamineIndexerModel CreateModel(KeyValuePair indexerKeyVal) - { - var indexer = indexerKeyVal.Value; - var indexName = indexerKeyVal.Key; - var indexerModel = new ExamineIndexerModel() - { - FieldDefinitions = indexer.FieldDefinitionCollection, - Name = indexName - }; - - var props = TypeHelper.CachedDiscoverableProperties(indexer.GetType(), mustWrite: false) - //ignore these properties - .Where(x => new[] {"IndexerData", "Description", "WorkingFolder"}.InvariantContains(x.Name) == false) - .OrderBy(x => x.Name); - - foreach (var p in props) - { - var val = p.GetValue(indexer, null); - if (val == null) - { - // Do not warn for new new attribute that is optional - if(string.Equals(p.Name, "DirectoryFactory", StringComparison.InvariantCultureIgnoreCase) == false) - Logger.Warn("Property value was null when setting up property on indexer: " + indexName + " property: " + p.Name); - - val = string.Empty; - } - indexerModel.ProviderProperties.Add(p.Name, val.ToString()); - } - - if (indexer is LuceneIndexer luceneIndexer) - { - indexerModel.IsLuceneIndex = true; - - if (luceneIndexer.IndexExists()) - { - indexerModel.IsHealthy = luceneIndexer.IsHealthy(out var indexError); - - if (indexerModel.IsHealthy == false) - { - //we cannot continue at this point - indexerModel.Error = indexError.ToString(); - return indexerModel; - } - - indexerModel.DocumentCount = luceneIndexer.GetIndexDocumentCount(); - indexerModel.FieldCount = luceneIndexer.GetIndexFieldCount(); - } - else - { - indexerModel.DocumentCount = 0; - indexerModel.FieldCount = 0; - } - } - return indexerModel; - } - - private HttpResponseMessage ValidateLuceneSearcher(string searcherName, out LuceneSearcher searcher) - { - foreach (var indexer in _examineManager.IndexProviders) - { - var s = indexer.Value.GetSearcher(); - var sName = (s as BaseLuceneSearcher)?.Name ?? string.Concat(indexer.Key, "Searcher"); - if (sName != searcherName) continue; - searcher = s as LuceneSearcher; - - //Found it, return OK - if (searcher != null) return Request.CreateResponse(HttpStatusCode.OK); - - //Return an error since it's not the right type - var response = Request.CreateResponse(HttpStatusCode.BadRequest); - response.Content = new StringContent($"The searcher {searcherName} is not of type {typeof(LuceneSearcher)}"); - response.ReasonPhrase = "Wrong Searcher Type"; - return response; - } - - searcher = null; - - var response1 = Request.CreateResponse(HttpStatusCode.BadRequest); - response1.Content = new StringContent($"No searcher found with name = {searcherName}"); - response1.ReasonPhrase = "Searcher Not Found"; - return response1; - } - - private HttpResponseMessage ValidateLuceneIndexer(string indexerName, out T indexer) - where T : class, IIndexer - { - indexer = null; - - if (_examineManager.IndexProviders.ContainsKey(indexerName) - && _examineManager.IndexProviders[indexerName] is T casted) - { - //return Ok! - indexer = casted; - return Request.CreateResponse(HttpStatusCode.OK); - } - - var response = Request.CreateResponse(HttpStatusCode.BadRequest); - response.Content = new StringContent($"No indexer found with name = {indexerName} of type {typeof(T)}"); - response.ReasonPhrase = "Indexer Not Found"; - return response; - } } } From 87df9b8f04747c8868857b221940bf846bad5dc3 Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Fri, 1 Jun 2018 21:39:29 +0100 Subject: [PATCH 016/134] Migrated DomainsApiController Moved action to exiting ContentController, moved viewmodels out into seperate files. --- .../umbraco_client/Dialogs/AssignDomain2.js | 2 +- src/Umbraco.Web/Editors/ContentController.cs | 156 +++++++++++++- .../Models/ContentEditing/DomainDisplay.cs | 16 ++ .../Models/ContentEditing/DomainSave.cs | 10 + src/Umbraco.Web/Umbraco.Web.csproj | 3 +- .../WebServices/DomainsApiController.cs | 190 ------------------ .../umbraco/dialogs/AssignDomain2.aspx.cs | 3 +- 7 files changed, 179 insertions(+), 201 deletions(-) create mode 100644 src/Umbraco.Web/Models/ContentEditing/DomainDisplay.cs create mode 100644 src/Umbraco.Web/Models/ContentEditing/DomainSave.cs delete mode 100644 src/Umbraco.Web/WebServices/DomainsApiController.cs diff --git a/src/Umbraco.Web.UI/umbraco_client/Dialogs/AssignDomain2.js b/src/Umbraco.Web.UI/umbraco_client/Dialogs/AssignDomain2.js index 07c16e4055..ddf38733e1 100644 --- a/src/Umbraco.Web.UI/umbraco_client/Dialogs/AssignDomain2.js +++ b/src/Umbraco.Web.UI/umbraco_client/Dialogs/AssignDomain2.js @@ -105,7 +105,7 @@ mask.show(); var data = { nodeId: self._opts.nodeId, language: self.language ? self.language : 0, domains: self.domains }; - $.post(self._opts.restServiceLocation + 'SaveLanguageAndDomains', ko.toJSON(data), function (json) { + $.post(self._opts.restServiceLocation + 'PostSaveLanguageAndDomains', ko.toJSON(data), function (json) { mask.hide(); if (json.Valid) { diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 2caa64fc98..4153661dcb 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -26,6 +26,7 @@ using Umbraco.Web.PublishedCache; using Umbraco.Core.Events; using Umbraco.Core.Models.Validation; using Umbraco.Web.Models; +using Umbraco.Web.WebServices; using Umbraco.Web._Legacy.Actions; using Constants = Umbraco.Core.Constants; using ContentVariation = Umbraco.Core.Models.ContentVariation; @@ -1001,7 +1002,7 @@ namespace Umbraco.Web.Editors /// /// Unpublishes a node with a given Id and returns the unpublished entity /// - /// The content id to unpublish + /// The content id to unpublish /// The culture variant for the content id to unpublish, if none specified will unpublish all variants of the content /// [EnsureUserPermissionForContent("id", 'U')] @@ -1023,17 +1024,156 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(Request.CreateValidationErrorResponse(content)); } else - { - //fixme should have a better localized method for when we have the UnpublishResultType.SuccessMandatoryCulture status + { + //fixme should have a better localized method for when we have the UnpublishResultType.SuccessMandatoryCulture status - content.AddSuccessNotification( - Services.TextService.Localize("content/unPublish"), - unpublishResult.Result == UnpublishResultType.SuccessVariant - ? Services.TextService.Localize("speechBubbles/contentVariationUnpublished", new[] { culture }) - : Services.TextService.Localize("speechBubbles/contentUnpublished")); + content.AddSuccessNotification( + Services.TextService.Localize("content/unPublish"), + unpublishResult.Result == UnpublishResultType.SuccessVariant + ? Services.TextService.Localize("speechBubbles/contentVariationUnpublished", new[] { culture }) + : Services.TextService.Localize("speechBubbles/contentUnpublished")); return content; } + } + + [HttpPost] + public DomainSave PostSaveLanguageAndDomains(DomainSave model) + { + var node = Services.ContentService.GetById(model.NodeId); + + if (node == null) + { + var response = Request.CreateResponse(HttpStatusCode.BadRequest); + response.Content = new StringContent($"There is no content node with id {model.NodeId}."); + response.ReasonPhrase = "Node Not Found."; + throw new HttpResponseException(response); + } + + var permission = Services.UserService.GetPermissions(Security.CurrentUser, node.Path); + + if (permission.AssignedPermissions.Contains(ActionAssignDomain.Instance.Letter.ToString(), StringComparer.Ordinal) == false) + { + var response = Request.CreateResponse(HttpStatusCode.BadRequest); + response.Content = new StringContent("You do not have permission to assign domains on that node."); + response.ReasonPhrase = "Permission Denied."; + throw new HttpResponseException(response); + } + + model.Valid = true; + var domains = Services.DomainService.GetAssignedDomains(model.NodeId, true).ToArray(); + var languages = Services.LocalizationService.GetAllLanguages().ToArray(); + var language = model.Language > 0 ? languages.FirstOrDefault(l => l.Id == model.Language) : null; + + // process wildcard + if (language != null) + { + // yet there is a race condition here... + var wildcard = domains.FirstOrDefault(d => d.IsWildcard); + if (wildcard != null) + { + wildcard.LanguageId = language.Id; + } + else + { + wildcard = new UmbracoDomain("*" + model.NodeId) + { + LanguageId = model.Language, + RootContentId = model.NodeId + }; + } + + var saveAttempt = Services.DomainService.Save(wildcard); + if (saveAttempt == false) + { + var response = Request.CreateResponse(HttpStatusCode.BadRequest); + response.Content = new StringContent("Saving domain failed"); + response.ReasonPhrase = saveAttempt.Result.Result.ToString(); + throw new HttpResponseException(response); + } + } + else + { + var wildcard = domains.FirstOrDefault(d => d.IsWildcard); + if (wildcard != null) + { + Services.DomainService.Delete(wildcard); + } + } + + // process domains + // delete every (non-wildcard) domain, that exists in the DB yet is not in the model + foreach (var domain in domains.Where(d => d.IsWildcard == false && model.Domains.All(m => m.Name.InvariantEquals(d.DomainName) == false))) + { + Services.DomainService.Delete(domain); + } + + var names = new List(); + + // create or update domains in the model + foreach (var domainModel in model.Domains.Where(m => string.IsNullOrWhiteSpace(m.Name) == false)) + { + language = languages.FirstOrDefault(l => l.Id == domainModel.Lang); + if (language == null) + { + continue; + } + + var name = domainModel.Name.ToLowerInvariant(); + if (names.Contains(name)) + { + domainModel.Duplicate = true; + continue; + } + names.Add(name); + var domain = domains.FirstOrDefault(d => d.DomainName.InvariantEquals(domainModel.Name)); + if (domain != null) + { + domain.LanguageId = language.Id; + Services.DomainService.Save(domain); + } + else if (Services.DomainService.Exists(domainModel.Name)) + { + domainModel.Duplicate = true; + var xdomain = Services.DomainService.GetByName(domainModel.Name); + var xrcid = xdomain.RootContentId; + if (xrcid.HasValue) + { + var xcontent = Services.ContentService.GetById(xrcid.Value); + var xnames = new List(); + while (xcontent != null) + { + xnames.Add(xcontent.Name); + if (xcontent.ParentId < -1) + xnames.Add("Recycle Bin"); + xcontent = xcontent.Parent(Services.ContentService); + } + xnames.Reverse(); + domainModel.Other = "/" + string.Join("/", xnames); + } + } + else + { + // yet there is a race condition here... + var newDomain = new UmbracoDomain(name) + { + LanguageId = domainModel.Lang, + RootContentId = model.NodeId + }; + var saveAttempt = Services.DomainService.Save(newDomain); + if (saveAttempt == false) + { + var response = Request.CreateResponse(HttpStatusCode.BadRequest); + response.Content = new StringContent("Saving new domain failed"); + response.ReasonPhrase = saveAttempt.Result.Result.ToString(); + throw new HttpResponseException(response); + } + } + } + + model.Valid = model.Domains.All(m => m.Duplicate == false); + + return model; } /// diff --git a/src/Umbraco.Web/Models/ContentEditing/DomainDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/DomainDisplay.cs new file mode 100644 index 0000000000..a6f7e499e4 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/DomainDisplay.cs @@ -0,0 +1,16 @@ +namespace Umbraco.Web.Models.ContentEditing +{ + public class DomainDisplay + { + public DomainDisplay(string name, int lang) + { + Name = name; + Lang = lang; + } + + public string Name { get; } + public int Lang { get; } + public bool Duplicate { get; set; } + public string Other { get; set; } + } +} diff --git a/src/Umbraco.Web/Models/ContentEditing/DomainSave.cs b/src/Umbraco.Web/Models/ContentEditing/DomainSave.cs new file mode 100644 index 0000000000..3ad19cfd60 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/DomainSave.cs @@ -0,0 +1,10 @@ +namespace Umbraco.Web.Models.ContentEditing +{ + public class DomainSave + { + public bool Valid { get; set; } + public int NodeId { get; set; } + public int Language { get; set; } + public DomainDisplay[] Domains { get; set; } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 5281b307aa..e126eed7a4 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -207,6 +207,8 @@ + + @@ -1417,7 +1419,6 @@ - diff --git a/src/Umbraco.Web/WebServices/DomainsApiController.cs b/src/Umbraco.Web/WebServices/DomainsApiController.cs deleted file mode 100644 index d74a225aee..0000000000 --- a/src/Umbraco.Web/WebServices/DomainsApiController.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Web.Http; -using Umbraco.Core; -using Umbraco.Core.Services; -using Umbraco.Core.Models; -using Umbraco.Web.WebApi; -//using umbraco.cms.businesslogic.language; -using Umbraco.Web.WebApi.Filters; -using Umbraco.Web._Legacy.Actions; - -namespace Umbraco.Web.WebServices -{ - /// - /// A REST controller used for managing domains. - /// - /// Nothing to do with Active Directory. - [ValidateAngularAntiForgeryToken] - public class DomainsApiController : UmbracoAuthorizedApiController - { - [HttpPost] - // can't pass multiple complex args in json post request... - public PostBackModel SaveLanguageAndDomains(PostBackModel model) - { - var node = Services.ContentService.GetById(model.NodeId); - - if (node == null) - { - var response = Request.CreateResponse(HttpStatusCode.BadRequest); - response.Content = new StringContent(string.Format("There is no content node with id {0}.", model.NodeId)); - response.ReasonPhrase = "Node Not Found."; - throw new HttpResponseException(response); - } - - var permission = Services.UserService.GetPermissions(Security.CurrentUser, node.Path); - - if (permission.AssignedPermissions.Contains(ActionAssignDomain.Instance.Letter.ToString(), StringComparer.Ordinal) == false) - { - var response = Request.CreateResponse(HttpStatusCode.BadRequest); - response.Content = new StringContent("You do not have permission to assign domains on that node."); - response.ReasonPhrase = "Permission Denied."; - throw new HttpResponseException(response); - } - - model.Valid = true; - var domains = Services.DomainService.GetAssignedDomains(model.NodeId, true).ToArray(); - var languages = Services.LocalizationService.GetAllLanguages().ToArray(); - var language = model.Language > 0 ? languages.FirstOrDefault(l => l.Id == model.Language) : null; - - // process wildcard - - if (language != null) - { - // yet there is a race condition here... - var wildcard = domains.FirstOrDefault(d => d.IsWildcard); - if (wildcard != null) - { - wildcard.LanguageId = language.Id; - } - else - { - wildcard = new UmbracoDomain("*" + model.NodeId) - { - LanguageId = model.Language, - RootContentId = model.NodeId - }; - } - - var saveAttempt = Services.DomainService.Save(wildcard); - if (saveAttempt == false) - { - var response = Request.CreateResponse(HttpStatusCode.BadRequest); - response.Content = new StringContent("Saving domain failed"); - response.ReasonPhrase = saveAttempt.Result.Result.ToString(); - throw new HttpResponseException(response); - } - } - else - { - var wildcard = domains.FirstOrDefault(d => d.IsWildcard); - if (wildcard != null) - { - Services.DomainService.Delete(wildcard); - } - } - - // process domains - - // delete every (non-wildcard) domain, that exists in the DB yet is not in the model - foreach (var domain in domains.Where(d => d.IsWildcard == false && model.Domains.All(m => m.Name.InvariantEquals(d.DomainName) == false))) - { - Services.DomainService.Delete(domain); - } - - - var names = new List(); - - // create or update domains in the model - foreach (var domainModel in model.Domains.Where(m => string.IsNullOrWhiteSpace(m.Name) == false)) - { - language = languages.FirstOrDefault(l => l.Id == domainModel.Lang); - if (language == null) - continue; - var name = domainModel.Name.ToLowerInvariant(); - if (names.Contains(name)) - { - domainModel.Duplicate = true; - continue; - } - names.Add(name); - var domain = domains.FirstOrDefault(d => d.DomainName.InvariantEquals(domainModel.Name)); - if (domain != null) - { - domain.LanguageId = language.Id; - Services.DomainService.Save(domain); - } - else if (Services.DomainService.Exists(domainModel.Name)) - { - domainModel.Duplicate = true; - var xdomain = Services.DomainService.GetByName(domainModel.Name); - var xrcid = xdomain.RootContentId; - if (xrcid.HasValue) - { - var xcontent = Services.ContentService.GetById(xrcid.Value); - var xnames = new List(); - while (xcontent != null) - { - xnames.Add(xcontent.Name); - if (xcontent.ParentId < -1) - xnames.Add("Recycle Bin"); - xcontent = xcontent.Parent(Services.ContentService); - } - xnames.Reverse(); - domainModel.Other = "/" + string.Join("/", xnames); - } - } - else - { - // yet there is a race condition here... - var newDomain = new UmbracoDomain(name) - { - LanguageId = domainModel.Lang, - RootContentId = model.NodeId - }; - var saveAttempt = Services.DomainService.Save(newDomain); - if (saveAttempt == false) - { - var response = Request.CreateResponse(HttpStatusCode.BadRequest); - response.Content = new StringContent("Saving new domain failed"); - response.ReasonPhrase = saveAttempt.Result.Result.ToString(); - throw new HttpResponseException(response); - } - } - } - - model.Valid = model.Domains.All(m => m.Duplicate == false); - - return model; - } - - #region Models - - public class PostBackModel - { - public bool Valid { get; set; } - public int NodeId { get; set; } - public int Language { get; set; } - public DomainModel[] Domains { get; set; } - } - - public class DomainModel - { - public DomainModel(string name, int lang) - { - Name = name; - Lang = lang; - } - - public string Name { get; private set; } - public int Lang { get; private set; } - public bool Duplicate { get; set; } - public string Other { get; set; } - } - - #endregion - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/AssignDomain2.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/AssignDomain2.aspx.cs index 51f1b4f114..00788fab3f 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/AssignDomain2.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/AssignDomain2.aspx.cs @@ -7,6 +7,7 @@ using Umbraco.Core.Services; using Umbraco.Web.UI.Pages; using Umbraco.Web; using Umbraco.Web.Composing; +using Umbraco.Web.Editors; using Umbraco.Web.WebServices; using Umbraco.Web._Legacy.Actions; @@ -75,7 +76,7 @@ namespace umbraco.dialogs protected string GetRestServicePath() { const string action = "ListDomains"; - var path = Url.GetUmbracoApiService(action); + var path = Url.GetUmbracoApiService(action); return path.TrimEnd(action).EnsureEndsWith('/'); } } From 1b42a2a6acfaadae1197f148983d9e34e39f39bb Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Sat, 2 Jun 2018 19:39:52 +0100 Subject: [PATCH 017/134] Removed SaveFileController Replaced with CodeFileController --- src/Umbraco.Web/Mvc/UrlHelperExtensions.cs | 13 +- src/Umbraco.Web/Umbraco.Web.csproj | 1 - .../WebServices/SaveFileController.cs | 318 ------------------ 3 files changed, 1 insertion(+), 331 deletions(-) delete mode 100644 src/Umbraco.Web/WebServices/SaveFileController.cs diff --git a/src/Umbraco.Web/Mvc/UrlHelperExtensions.cs b/src/Umbraco.Web/Mvc/UrlHelperExtensions.cs index 19ae37b9cf..3ee94abef7 100644 --- a/src/Umbraco.Web/Mvc/UrlHelperExtensions.cs +++ b/src/Umbraco.Web/Mvc/UrlHelperExtensions.cs @@ -75,18 +75,7 @@ namespace Umbraco.Web.Mvc } return false; } - - /// - /// Returns the base path (not including the 'action') of the MVC controller "SaveFileController" - /// - /// - /// - public static string GetSaveFileServicePath(this UrlHelper url) - { - var result = url.Action("SavePartialView", "SaveFile", new {area = UmbracoConfig.For.GlobalSettings().GetUmbracoMvcArea()}); - return result.TrimEnd("SavePartialView").EnsureEndsWith('/'); - } - + /// /// Returns the base path (not including the 'action') of the MVC controller "BulkPublishController" /// diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index e126eed7a4..756d78196b 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1423,7 +1423,6 @@ - Component diff --git a/src/Umbraco.Web/WebServices/SaveFileController.cs b/src/Umbraco.Web/WebServices/SaveFileController.cs deleted file mode 100644 index 615b45034e..0000000000 --- a/src/Umbraco.Web/WebServices/SaveFileController.cs +++ /dev/null @@ -1,318 +0,0 @@ -using System; -using System.Web.Mvc; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using Umbraco.Core.Services; -using Umbraco.Web.Mvc; -using System.Collections.Generic; -using umbraco.cms.presentation.Trees; -using Umbraco.Core; -using Umbraco.Core.Services.Implement; - -namespace Umbraco.Web.WebServices -{ - /// - /// Represents REST controller used to save files such as templates, partial views, macro files, etc. - /// - /// This isn't fully implemented yet but we should migrate all of the logic - /// in the umbraco.presentation.webservices.codeEditorSave over to this controller. - [ValidateMvcAngularAntiForgeryToken] - public class SaveFileController : UmbracoAuthorizedController - { - /// - /// Saves a partial view macro - /// - /// - /// - /// - /// - [HttpPost] - public JsonResult SavePartialViewMacro(string filename, string oldName, string contents) - { - var svce = (FileService) Services.FileService; - - return SavePartialView(svce, - filename, oldName, contents, - "MacroPartials/", - (s, n) => s.GetPartialViewMacro(n), - (s, v) => s.ValidatePartialViewMacro((PartialView) v), - (s, v) => s.SavePartialViewMacro(v)); - } - - /// - /// Saves a partial view - /// - /// - /// - /// - /// - [HttpPost] - public JsonResult SavePartialView(string filename, string oldName, string contents) - { - var svce = (FileService) Services.FileService; - - return SavePartialView(svce, - filename, oldName, contents, - "Partials/", - (s, n) => s.GetPartialView(n), - (s, v) => s.ValidatePartialView((PartialView) v), - (s, v) => s.SavePartialView(v)); - } - - private JsonResult SavePartialView(IFileService svce, - string filename, string oldname, string contents, - string pathPrefix, - Func get, - Func validate, - Func> save) - { - // sanitize input - partial view names have an extension - filename = filename - .Replace('\\', '/') - .TrimStart('/'); - - // sharing the editor with partial views & partial view macros, - // using path prefix to differenciate, - // but the file service manages different filesystems, - // and we need to come back to filesystem-relative paths - - // not sure why we still need this but not going to change it now - - if (filename.InvariantStartsWith(pathPrefix)) - filename = filename.TrimStart(pathPrefix); - - if (oldname != null) - { - oldname = oldname.TrimStart('/', '\\'); - if (oldname.InvariantStartsWith(pathPrefix)) - oldname = oldname.TrimStart(pathPrefix); - } - - var currentView = oldname.IsNullOrWhiteSpace() - ? get(svce, filename) - : get(svce, oldname); - - if (currentView == null) - currentView = new PartialView(PartialViewType.PartialView, filename); - else - currentView.Path = filename; - currentView.Content = contents; - - - - - Attempt attempt; - try - { - var partialView = currentView as PartialView; - if (partialView != null && validate != null && validate(svce, partialView) == false) - return Failed(Services.TextService.Localize("speechBubbles/partialViewErrorText"), Services.TextService.Localize("speechBubbles/partialViewErrorHeader"), - new FileSecurityException("File '" + currentView.Path + "' is not a valid partial view file.")); - - attempt = save(svce, currentView); - } - catch (Exception e) - { - return Failed(Services.TextService.Localize("speechBubbles/partialViewErrorText"), Services.TextService.Localize("speechBubbles/partialViewErrorHeader"), e); - } - - if (attempt.Success == false) - { - return Failed(Services.TextService.Localize("speechBubbles/partialViewErrorText"), Services.TextService.Localize("speechBubbles/partialViewErrorHeader"), - attempt.Exception); - } - - - return Success(Services.TextService.Localize("speechBubbles/partialViewSavedText"), Services.TextService.Localize("speechBubbles/partialViewSavedHeader"), new { name = currentView.Name, path = currentView.Path }); - } - - // fixme - remove code - ///// - ///// Saves a template - ///// - ///// - ///// - ///// - ///// - ///// - ///// - //[HttpPost] - //public JsonResult SaveTemplate(string templateName, string templateAlias, string templateContents, int templateId, int masterTemplateId) - //{ - // //TODO: Change this over to use the new API - Also this will be migrated to a TemplateEditor or ViewEditor when it's all moved to angular - - // Template t; - // bool pathChanged = false; - // try - // { - // t = new Template(templateId) - // { - // Text = templateName.CleanForXss('[', ']', '(', ')', ':'), - // Alias = templateAlias.CleanForXss('[', ']', '(', ')', ':'), - // Design = templateContents - // }; - - // //check if the master page has changed - we need to normalize both - if it's 0 or -1, then make it 0... this is easy - // // to do with Math.Max - // if (Math.Max(t.MasterTemplate, 0) != Math.Max(masterTemplateId, 0)) - // { - // t.MasterTemplate = Math.Max(masterTemplateId, 0); - // pathChanged = true; - // } - // } - // catch (ArgumentException ex) - // { - // //the template does not exist - // return Failed("Template does not exist", Services.TextService.Localize("speechBubbles/templateErrorHeader"), ex); - // } - - // try - // { - // t.Save(); - - // //ensure the correct path is synced as the parent might have been changed - // // http://issues.umbraco.org/issue/U4-2300 - // if (pathChanged) - // { - // //need to re-look it up - // t = new Template(templateId); - // } - // var syncPath = "-1,init," + t.Path.Replace("-1,", ""); - - // return Success(Services.TextService.Localize("speechBubbles/templateSavedText"), Services.TextService.Localize("speechBubbles/templateSavedHeader"), - // new - // { - // path = syncPath, - // contents = t.Design, - // alias = t.Alias // might have been updated! - // }); - // } - // catch (Exception ex) - // { - // return Failed(Services.TextService.Localize("speechBubbles/templateErrorText"), Services.TextService.Localize("speechBubbles/templateErrorHeader"), ex); - // } - //} - - //[HttpPost] - //public JsonResult SaveXslt(string fileName, string oldName, string fileContents, bool ignoreDebugging) - //{ - - //} - - [HttpPost] - public JsonResult SaveScript(string filename, string oldName, string contents) - { - // sanitize input - script names have an extension - filename = filename - .Replace('\\', '/') - .TrimStart('/'); - - var svce = (FileService) Services.FileService; - var script = svce.GetScriptByName(oldName); - if (script == null) - script = new Script(filename); - else - script.Path = filename; - script.Content = contents; - - try - { - if (svce.ValidateScript(script) == false) - return Failed(Services.TextService.Localize("speechBubbles/scriptErrorText"), Services.TextService.Localize("speechBubbles/scriptErrorHeader"), - new FileSecurityException("File '" + filename + "' is not a valid script file.")); - - svce.SaveScript(script); - } - catch (Exception e) - { - return Failed(Services.TextService.Localize("speechBubbles/scriptErrorText"), Services.TextService.Localize("speechBubbles/scriptErrorHeader"), e); - } - - return Success(Services.TextService.Localize("speechBubbles/scriptSavedText"), Services.TextService.Localize("speechBubbles/scriptSavedHeader"), - new - { - path = BaseTree.GetTreePathFromFilePath(script.Path), - name = script.Path, - url = script.VirtualPath, - contents = script.Content - }); - } - - [HttpPost] - public JsonResult SaveStylesheet(string filename, string oldName, string contents) - { - // sanitize input - stylesheet names have no extension - filename = filename - .Replace('\\', '/') - .TrimStart('/') - .EnsureEndsWith(".css"); - - var svce = (FileService) Services.FileService; - var stylesheet = svce.GetStylesheetByName(oldName); - if (stylesheet == null) - stylesheet = new Stylesheet(filename); - else - stylesheet.Path = filename; - stylesheet.Content = contents; - - try - { - if (svce.ValidateStylesheet(stylesheet) == false) - return Failed(Services.TextService.Localize("speechBubbles/cssErrorText"), Services.TextService.Localize("speechBubbles/cssErrorHeader"), - new FileSecurityException("File '" + filename + "' is not a valid stylesheet file.")); - - svce.SaveStylesheet(stylesheet); - } - catch (Exception e) - { - return Failed(Services.TextService.Localize("speechBubbles/cssErrorText"), Services.TextService.Localize("speechBubbles/cssErrorHeader"), e); - } - - return Success(Services.TextService.Localize("speechBubbles/cssSavedText"), Services.TextService.Localize("speechBubbles/cssSavedHeader"), - new - { - path = BaseTree.GetTreePathFromFilePath(stylesheet.Path), - name = stylesheet.Path, - url = stylesheet.VirtualPath, - contents = stylesheet.Content - }); - } - - /// - /// Returns a successful message - /// - /// The message to display in the speach bubble - /// The header to display in the speach bubble - /// - /// - private JsonResult Success(string message, string header, object additionalVals = null) - { - var d = additionalVals == null ? new Dictionary() : additionalVals.ToDictionary(); - d["success"] = true; - d["message"] = message; - d["header"] = header; - - return Json(d); - } - - /// - /// Returns a failed message - /// - /// The message to display in the speach bubble - /// The header to display in the speach bubble - /// The exception if there was one - /// - private JsonResult Failed(string message, string header, Exception exception = null) - { - if (exception != null) - Logger.Error("An error occurred saving a file. " + message, exception); - return Json(new - { - success = false, - header = header, - message = message + (exception == null ? "" : (exception.Message + ". Check log for details.")) - }); - } - } -} From cca3c5df781633e4cd27c5b9b343806799bcd646 Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Sat, 2 Jun 2018 20:00:07 +0100 Subject: [PATCH 018/134] Removed unused CoreStringsController --- src/Umbraco.Web/Umbraco.Web.csproj | 1 - .../WebServices/CoreStringsController.cs | 33 ------------------- 2 files changed, 34 deletions(-) delete mode 100644 src/Umbraco.Web/WebServices/CoreStringsController.cs diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 756d78196b..e7d3e124e7 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1418,7 +1418,6 @@ Reference.map - diff --git a/src/Umbraco.Web/WebServices/CoreStringsController.cs b/src/Umbraco.Web/WebServices/CoreStringsController.cs deleted file mode 100644 index 2f84e10d54..0000000000 --- a/src/Umbraco.Web/WebServices/CoreStringsController.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Web.Mvc; -using Umbraco.Core; -using Umbraco.Core.Strings; -using Umbraco.Web.Composing; -using Umbraco.Web.Mvc; - -namespace Umbraco.Web.WebServices -{ - /// - /// Represents a REST controller used for accessing Core.Strings services. - /// - public class CoreStringsController : UmbracoAuthorizedController - { - [HttpGet] - [ValidateInput(false)] - public JsonResult ToSafeAlias(string value, bool camelCase = true) - { - // always return a proper camel-cased alias - // when checking... javascript does a case-unsensitive comparison - return value == null - ? Json(new {error = "no value."}, JsonRequestBehavior.AllowGet) - : Json(new { alias = value.ToCleanString(CleanStringType.Alias | CleanStringType.CamelCase) }, JsonRequestBehavior.AllowGet); - } - - [HttpGet] - public JavaScriptResult ServicesJavaScript() - { - var controllerPath = Url.GetCoreStringsControllerPath(); - var js = Current.ShortStringHelper.GetShortStringServicesJavaScript(controllerPath); - return JavaScript(js); - } - } -} From 222cb25cfde1db1974027d57b5304afb32acc58c Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Sun, 3 Jun 2018 14:42:10 +0100 Subject: [PATCH 019/134] Moved XmlDataIntegrityController, PublishedStatusController, and NuCacheStatusController out of WebServices --- .../{WebServices => Editors}/NuCacheStatusController.cs | 2 +- .../{WebServices => Editors}/PublishedStatusController.cs | 2 +- .../{WebServices => Editors}/XmlDataIntegrityController.cs | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) rename src/Umbraco.Web/{WebServices => Editors}/NuCacheStatusController.cs (98%) rename src/Umbraco.Web/{WebServices => Editors}/PublishedStatusController.cs (97%) rename src/Umbraco.Web/{WebServices => Editors}/XmlDataIntegrityController.cs (98%) diff --git a/src/Umbraco.Web/WebServices/NuCacheStatusController.cs b/src/Umbraco.Web/Editors/NuCacheStatusController.cs similarity index 98% rename from src/Umbraco.Web/WebServices/NuCacheStatusController.cs rename to src/Umbraco.Web/Editors/NuCacheStatusController.cs index d1c9c0451e..b9cee665cb 100644 --- a/src/Umbraco.Web/WebServices/NuCacheStatusController.cs +++ b/src/Umbraco.Web/Editors/NuCacheStatusController.cs @@ -6,7 +6,7 @@ using Umbraco.Web.PublishedCache; using Umbraco.Web.PublishedCache.NuCache; using Umbraco.Web.WebApi; -namespace Umbraco.Web.WebServices +namespace Umbraco.Web.Editors { public class NuCacheStatusController : UmbracoAuthorizedApiController { diff --git a/src/Umbraco.Web/WebServices/PublishedStatusController.cs b/src/Umbraco.Web/Editors/PublishedStatusController.cs similarity index 97% rename from src/Umbraco.Web/WebServices/PublishedStatusController.cs rename to src/Umbraco.Web/Editors/PublishedStatusController.cs index d5846cce10..087b96a241 100644 --- a/src/Umbraco.Web/WebServices/PublishedStatusController.cs +++ b/src/Umbraco.Web/Editors/PublishedStatusController.cs @@ -3,7 +3,7 @@ using System.Web.Http; using Umbraco.Web.PublishedCache; using Umbraco.Web.WebApi; -namespace Umbraco.Web.WebServices +namespace Umbraco.Web.Editors { public class PublishedStatusController : UmbracoAuthorizedApiController { diff --git a/src/Umbraco.Web/WebServices/XmlDataIntegrityController.cs b/src/Umbraco.Web/Editors/XmlDataIntegrityController.cs similarity index 98% rename from src/Umbraco.Web/WebServices/XmlDataIntegrityController.cs rename to src/Umbraco.Web/Editors/XmlDataIntegrityController.cs index 5c16c83e57..4862b86f69 100644 --- a/src/Umbraco.Web/WebServices/XmlDataIntegrityController.cs +++ b/src/Umbraco.Web/Editors/XmlDataIntegrityController.cs @@ -5,7 +5,7 @@ using Umbraco.Web.PublishedCache.XmlPublishedCache; using Umbraco.Web.WebApi; using Umbraco.Web.WebApi.Filters; -namespace Umbraco.Web.WebServices +namespace Umbraco.Web.Editors { [ValidateAngularAntiForgeryToken] public class XmlDataIntegrityController : UmbracoAuthorizedApiController diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index e7d3e124e7..6d209b4cb7 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -443,8 +443,8 @@ - - + + @@ -1429,7 +1429,7 @@ Component - + From 84444232014b68b5460be8cb736fc197a3f9551a Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Mon, 4 Jun 2018 21:50:58 +0100 Subject: [PATCH 020/134] Removed unused bulk publish controller --- src/Umbraco.Web/Mvc/UrlHelperExtensions.cs | 22 ---- src/Umbraco.Web/Umbraco.Web.csproj | 1 - .../WebServices/BulkPublishController.cs | 101 ------------------ 3 files changed, 124 deletions(-) delete mode 100644 src/Umbraco.Web/WebServices/BulkPublishController.cs diff --git a/src/Umbraco.Web/Mvc/UrlHelperExtensions.cs b/src/Umbraco.Web/Mvc/UrlHelperExtensions.cs index 3ee94abef7..3e29d88d5f 100644 --- a/src/Umbraco.Web/Mvc/UrlHelperExtensions.cs +++ b/src/Umbraco.Web/Mvc/UrlHelperExtensions.cs @@ -75,27 +75,5 @@ namespace Umbraco.Web.Mvc } return false; } - - /// - /// Returns the base path (not including the 'action') of the MVC controller "BulkPublishController" - /// - /// - /// - public static string GetBulkPublishServicePath(this UrlHelper url) - { - var result = url.Action("PublishDocument", "BulkPublish", new { area = UmbracoConfig.For.GlobalSettings().GetUmbracoMvcArea() }); - return result.TrimEnd("PublishDocument").EnsureEndsWith('/'); - } - - /// - /// Returns the base path (not including the 'action') of the MVC controller "CoreStringsController" - /// - /// The url helper. - /// The base path of the controller. - public static string GetCoreStringsControllerPath(this UrlHelper url) - { - var result = url.Action("ToSafeAlias", "CoreStrings", new { area = UmbracoConfig.For.GlobalSettings().GetUmbracoMvcArea() }); - return result.TrimEnd("ToSafeAlias"); - } } } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 6d209b4cb7..664b5e275a 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1417,7 +1417,6 @@ True Reference.map - diff --git a/src/Umbraco.Web/WebServices/BulkPublishController.cs b/src/Umbraco.Web/WebServices/BulkPublishController.cs deleted file mode 100644 index 714c1ac0db..0000000000 --- a/src/Umbraco.Web/WebServices/BulkPublishController.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Web.Mvc; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Services; -using Umbraco.Web.Mvc; - -namespace Umbraco.Web.WebServices -{ - /// - /// Represents a REST controller used for the publish dialog in order to bulk-publish bulk content items. - /// - [ValidateMvcAngularAntiForgeryToken] - public class BulkPublishController : UmbracoAuthorizedController - { - /// - /// Publishes an document - /// - /// - /// true to publish descendants as well - /// true to publish documents that are unpublished - /// A Json array containing objects with the child id's of the document and it's current published status - [HttpPost] - public JsonResult PublishDocument(int documentId, bool publishDescendants, bool includeUnpublished) - { - var content = Services.ContentService.GetById(documentId); - - if (publishDescendants == false) - { - content.TryPublishValues(); // fixme variants? validation - when this returns null? - var result = Services.ContentService.SaveAndPublish(content, Security.CurrentUser.Id); - return Json(new - { - success = result.Success, - message = GetMessageForStatus(result) - }); - } - else - { - // fixme variants? - var result = Services.ContentService.SaveAndPublishBranch(content, includeUnpublished); - - return Json(new - { - success = result.All(x => x.Success), - message = GetMessageForStatuses(result.ToArray(), content) - }); - } - } - - private string GetMessageForStatuses(PublishResult[] statuses, IContent doc) - { - //if all are successful then just say it was successful - if (statuses.All(x => x.Success)) - { - return Services.TextService.Localize("publish/nodePublishAll", new[] { doc.Name}); - } - - //if they are not all successful the we'll add each error message to the output (one per line) - var sb = new StringBuilder(); - foreach (var msg in statuses - .Where(x => ((int)x.Result) >= 10) - .Select(GetMessageForStatus) - .Where(msg => msg.IsNullOrWhiteSpace() == false)) - { - sb.AppendLine(msg.Trim()); - } - return sb.ToString(); - } - - private string GetMessageForStatus(PublishResult status) - { - switch (status.Result) - { - case PublishResultType.Success: - case PublishResultType.SuccessAlready: - return Services.TextService.Localize("publish/nodePublish", new[] { status.Content.Name}); - case PublishResultType.FailedPathNotPublished: - return Services.TextService.Localize("publish/contentPublishedFailedByParent", - new [] { string.Format("{0} ({1})", status.Content.Name, status.Content.Id) }); - case PublishResultType.FailedHasExpired: - case PublishResultType.FailedAwaitingRelease: - case PublishResultType.FailedIsTrashed: - return "Cannot publish document with a status of " + status.Result; - case PublishResultType.FailedCancelledByEvent: - return Services.TextService.Localize("publish/contentPublishedFailedByEvent", - new [] { string.Format("'{0}' ({1})", status.Content.Name, status.Content.Id) }); - case PublishResultType.FailedContentInvalid: - return Services.TextService.Localize("publish/contentPublishedFailedInvalid", - new []{ - string.Format("'{0}' ({1})", status.Content.Name, status.Content.Id), - string.Format("'{0}'", string.Join(", ", status.InvalidProperties.Select(x => x.Alias))) - }); - default: - return status.Result.ToString(); - } - } - } -} From dd7d6ba392a420e9f32cf69e6d75db3da6b8a275 Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Thu, 7 Jun 2018 21:28:38 +0100 Subject: [PATCH 021/134] Removed unused EmbedMediaService --- src/Umbraco.Web/Umbraco.Web.csproj | 1 - .../WebServices/EmbedMediaService.cs | 82 ------------------- 2 files changed, 83 deletions(-) delete mode 100644 src/Umbraco.Web/WebServices/EmbedMediaService.cs diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 664b5e275a..9442a806d6 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1417,7 +1417,6 @@ True Reference.map - diff --git a/src/Umbraco.Web/WebServices/EmbedMediaService.cs b/src/Umbraco.Web/WebServices/EmbedMediaService.cs deleted file mode 100644 index 00d0ad8ede..0000000000 --- a/src/Umbraco.Web/WebServices/EmbedMediaService.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Text.RegularExpressions; -using System.Web; -using System.Web.Script.Serialization; -using System.Xml; -using Umbraco.Core.Configuration; -using Umbraco.Core.Media; - -namespace Umbraco.Web.WebServices -{ - //TODO: Convert this to MVC and see if we still need it - - public class EmbedMediaService - { - public static string Embed() - { - var currentUser = UmbracoContext.Current.Security.CurrentUser; - - if (currentUser == null) - throw new UnauthorizedAccessException("You must be logged in to use this service"); - - var url = HttpContext.Current.Request.Form["url"]; - var width = int.Parse(HttpContext.Current.Request.Form["width"]); - var height = int.Parse(HttpContext.Current.Request.Form["height"]); - - var result = new Result(); - - //todo cache embed doc - var xmlConfig = new XmlDocument(); - xmlConfig.Load(GlobalSettings.FullPathToRoot + Path.DirectorySeparatorChar + "config" + Path.DirectorySeparatorChar + "EmbeddedMedia.config"); - - foreach (XmlNode node in xmlConfig.SelectNodes("//provider")) - { - var regexPattern = new Regex(node.SelectSingleNode("./urlShemeRegex").InnerText, RegexOptions.IgnoreCase); - - if (regexPattern.IsMatch(url)) - { - var prov = (IEmbedProvider)Activator.CreateInstance(Type.GetType(node.Attributes["type"].Value)); - - if (node.Attributes["supportsDimensions"] != null) - result.SupportsDimensions = node.Attributes["supportsDimensions"].Value == "True"; - else - result.SupportsDimensions = prov.SupportsDimensions; - - var settings = node.ChildNodes.Cast().ToDictionary(settingNode => settingNode.Name); - - foreach (var prop in prov.GetType().GetProperties().Where(prop => prop.IsDefined(typeof(ProviderSetting), true))) - { - - if (settings.Any(s => s.Key.ToLower() == prop.Name.ToLower())) - { - var setting = settings.FirstOrDefault(s => s.Key.ToLower() == prop.Name.ToLower()).Value; - var settingType = typeof(Media.EmbedProviders.Settings.String); - - if (setting.Attributes["type"] != null) - settingType = Type.GetType(setting.Attributes["type"].Value); - - var settingProv = (IEmbedSettingProvider)Activator.CreateInstance(settingType); - prop.SetValue(prov, settingProv.GetSetting(settings.FirstOrDefault(s => s.Key.ToLower() == prop.Name.ToLower()).Value), null); - } - } - try - { - result.Markup = prov.GetMarkup(url, width, height); - result.Status = Status.Success; - } - catch - { - result.Status = Status.Error; - } - - return new JavaScriptSerializer().Serialize(result); - } - } - - result.Status = Status.NotSupported; - return new JavaScriptSerializer().Serialize(result); - } - } -} From bd7aea31ee9f7130d864fea5f1a2c10a3b8a901c Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Thu, 7 Jun 2018 21:32:48 +0100 Subject: [PATCH 022/134] Removed unused Examine Management Controller actions --- src/Umbraco.Web/Umbraco.Web.csproj | 1 - .../ExamineManagementApiController.cs | 86 ------------------- 2 files changed, 87 deletions(-) delete mode 100644 src/Umbraco.Web/WebServices/ExamineManagementApiController.cs diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 9442a806d6..2342da57a7 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1417,7 +1417,6 @@ True Reference.map - diff --git a/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs b/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs deleted file mode 100644 index 193e47c720..0000000000 --- a/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Reflection; -using System.Web.Http; -using Examine; -using Examine.LuceneEngine; -using Examine.LuceneEngine.Providers; -using Examine.Providers; -using Lucene.Net.Search; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Logging; -using Umbraco.Core.Composing; -using Umbraco.Core.Services; -using Umbraco.Examine; -using Umbraco.Web.Search; -using Umbraco.Web.WebApi; -using Umbraco.Web.WebApi.Filters; - -namespace Umbraco.Web.WebServices -{ - [ValidateAngularAntiForgeryToken] - [Obsolete] - public class ExamineManagementApiController : UmbracoAuthorizedApiController - { - public ExamineManagementApiController(IExamineManager examineManager, ILogger logger, IRuntimeCacheProvider runtimeCacheProvider) - { - _examineManager = examineManager; - _logger = logger; - _runtimeCacheProvider = runtimeCacheProvider; - } - - private readonly IExamineManager _examineManager; - private readonly ILogger _logger; - private readonly IRuntimeCacheProvider _runtimeCacheProvider; - - /// - /// Checks if the member internal index is consistent with the data stored in the database - /// - /// - [HttpGet] - public bool CheckMembersInternalIndex() - { - var total = Services.MemberService.Count(); - - var searcher = _examineManager.GetSearcher(Constants.Examine.InternalMemberIndexer); - var criteria = searcher.CreateCriteria().RawQuery("__IndexType:member"); - var totalIndexed = searcher.Search(criteria); - return total == totalIndexed.TotalItemCount; - } - - /// - /// Checks if the media internal index is consistent with the data stored in the database - /// - /// - [HttpGet] - public bool CheckMediaInternalIndex() - { - var total = Services.MediaService.Count(); - - var searcher = _examineManager.GetSearcher(Constants.Examine.InternalIndexer); - var criteria = searcher.CreateCriteria().RawQuery("__IndexType:media"); - var totalIndexed = searcher.Search(criteria); - return total == totalIndexed.TotalItemCount; - } - - /// - /// Checks if the content internal index is consistent with the data stored in the database - /// - /// - [HttpGet] - public bool CheckContentInternalIndex() - { - var total = Services.ContentService.Count(); - - var searcher = _examineManager.GetSearcher(Constants.Examine.InternalIndexer); - var criteria = searcher.CreateCriteria().RawQuery("__IndexType:content"); - var totalIndexed = searcher.Search(criteria); - return total == totalIndexed.TotalItemCount; - } - } -} From 5a43f6b6fe476e31fe9a673dc93fb5d48c9a6f1e Mon Sep 17 00:00:00 2001 From: James Coxhead Date: Sun, 10 Jun 2018 20:00:07 +0100 Subject: [PATCH 023/134] Moved remaining classes out of WebServices --- .../{WebServices => }/TagsController.cs | 157 +++++++------- src/Umbraco.Web/Umbraco.Web.csproj | 10 +- .../UmbracoAuthorizedHttpHandler.cs | 202 +++++++++--------- .../{WebServices => }/UmbracoHttpHandler.cs | 150 ++++++------- .../{WebServices => }/UmbracoWebService.cs | 152 ++++++------- .../controls/Tree/CustomTreeService.cs | 1 + .../UmbracoAuthorizedWebService.cs | 192 +++++++++-------- .../umbraco/webservices/nodeSorter.asmx.cs | 1 - 8 files changed, 434 insertions(+), 431 deletions(-) rename src/Umbraco.Web/{WebServices => }/TagsController.cs (97%) rename src/Umbraco.Web/{WebServices => }/UmbracoAuthorizedHttpHandler.cs (96%) rename src/Umbraco.Web/{WebServices => }/UmbracoHttpHandler.cs (95%) rename src/Umbraco.Web/{WebServices => }/UmbracoWebService.cs (95%) rename src/Umbraco.Web/{WebServices => umbraco.presentation/umbraco/webservices}/UmbracoAuthorizedWebService.cs (96%) diff --git a/src/Umbraco.Web/WebServices/TagsController.cs b/src/Umbraco.Web/TagsController.cs similarity index 97% rename from src/Umbraco.Web/WebServices/TagsController.cs rename to src/Umbraco.Web/TagsController.cs index 6241cfacf0..4d82b8928d 100644 --- a/src/Umbraco.Web/WebServices/TagsController.cs +++ b/src/Umbraco.Web/TagsController.cs @@ -1,78 +1,79 @@ -using System.Collections.Generic; -using Umbraco.Web.Models; -using Umbraco.Web.WebApi; - -namespace Umbraco.Web.WebServices -{ - /// - /// A public web service for querying tags - /// - /// - /// This controller does not contain methods to query for content, media or members based on tags, those methods would require - /// authentication and should not be exposed publicly. - /// - public class TagsController : UmbracoApiController - { - /// - /// Get every tag stored in the database (with optional group) - /// - public IEnumerable GetAllTags(string group = null) - { - return Umbraco.TagQuery.GetAllTags(group); - } - - /// - /// Get all tags for content items (with optional group) - /// - /// - /// - public IEnumerable GetAllContentTags(string group = null) - { - return Umbraco.TagQuery.GetAllContentTags(group); - } - - /// - /// Get all tags for media items (with optional group) - /// - /// - /// - public IEnumerable GetAllMediaTags(string group = null) - { - return Umbraco.TagQuery.GetAllMediaTags(group); - } - - /// - /// Get all tags for member items (with optional group) - /// - /// - /// - public IEnumerable GetAllMemberTags(string group = null) - { - return Umbraco.TagQuery.GetAllMemberTags(group); - } - - /// - /// Returns all tags attached to a property by entity id - /// - /// - /// - /// - /// - public IEnumerable GetTagsForProperty(int contentId, string propertyTypeAlias, string tagGroup = null) - { - return Umbraco.TagQuery.GetTagsForProperty(contentId, propertyTypeAlias, tagGroup); - } - - /// - /// Returns all tags attached to an entity (content, media or member) by entity id - /// - /// - /// - /// - public IEnumerable GetTagsForEntity(int contentId, string tagGroup = null) - { - return Umbraco.TagQuery.GetTagsForEntity(contentId, tagGroup); - } - - } -} +using System.Collections.Generic; +using Umbraco.Web.Models; +using Umbraco.Web.WebApi; + +namespace Umbraco.Web.WebServices +{ + /// + /// A public web service for querying tags + /// + /// + /// This controller does not contain methods to query for content, media or members based on tags, those methods would require + /// authentication and should not be exposed publicly. + /// + // TODO: This controller should be moved to a more suitable place. + public class TagsController : UmbracoApiController + { + /// + /// Get every tag stored in the database (with optional group) + /// + public IEnumerable GetAllTags(string group = null) + { + return Umbraco.TagQuery.GetAllTags(group); + } + + /// + /// Get all tags for content items (with optional group) + /// + /// + /// + public IEnumerable GetAllContentTags(string group = null) + { + return Umbraco.TagQuery.GetAllContentTags(group); + } + + /// + /// Get all tags for media items (with optional group) + /// + /// + /// + public IEnumerable GetAllMediaTags(string group = null) + { + return Umbraco.TagQuery.GetAllMediaTags(group); + } + + /// + /// Get all tags for member items (with optional group) + /// + /// + /// + public IEnumerable GetAllMemberTags(string group = null) + { + return Umbraco.TagQuery.GetAllMemberTags(group); + } + + /// + /// Returns all tags attached to a property by entity id + /// + /// + /// + /// + /// + public IEnumerable GetTagsForProperty(int contentId, string propertyTypeAlias, string tagGroup = null) + { + return Umbraco.TagQuery.GetTagsForProperty(contentId, propertyTypeAlias, tagGroup); + } + + /// + /// Returns all tags attached to an entity (content, media or member) by entity id + /// + /// + /// + /// + public IEnumerable GetTagsForEntity(int contentId, string tagGroup = null) + { + return Umbraco.TagQuery.GetTagsForEntity(contentId, tagGroup); + } + + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 2342da57a7..4d61686c61 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1417,13 +1417,13 @@ True Reference.map - - - + + + Component - - + + Component diff --git a/src/Umbraco.Web/WebServices/UmbracoAuthorizedHttpHandler.cs b/src/Umbraco.Web/UmbracoAuthorizedHttpHandler.cs similarity index 96% rename from src/Umbraco.Web/WebServices/UmbracoAuthorizedHttpHandler.cs rename to src/Umbraco.Web/UmbracoAuthorizedHttpHandler.cs index 248eea3d93..42e3708d1c 100644 --- a/src/Umbraco.Web/WebServices/UmbracoAuthorizedHttpHandler.cs +++ b/src/Umbraco.Web/UmbracoAuthorizedHttpHandler.cs @@ -1,101 +1,101 @@ -using System; -using System.Security; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Web.Security; -using Umbraco.Core.Models.Membership; -using Umbraco.Core.Services; - -namespace Umbraco.Web.WebServices -{ - public abstract class UmbracoAuthorizedHttpHandler : UmbracoHttpHandler - { - protected UmbracoAuthorizedHttpHandler() - { } - - protected UmbracoAuthorizedHttpHandler(UmbracoContext umbracoContext, ServiceContext services, CacheHelper appCache) - : base(umbracoContext, services, appCache) - { - } - - private bool _hasValidated = false; - - /// - /// Checks if the umbraco context id is valid - /// - /// - /// - protected bool ValidateUserContextId(string currentUmbracoUserContextId) - { - return UmbracoContext.Security.ValidateCurrentUser(); - } - - /// - /// Checks if the username/password credentials are valid - /// - /// - /// - /// - protected bool ValidateCredentials(string username, string password) - { - return UmbracoContext.Security.ValidateBackOfficeCredentials(username, password); - } - - /// - /// Validates the user for access to a certain application - /// - /// The application alias. - /// true if an exception should be thrown if authorization fails - /// - protected bool AuthorizeRequest(string app, bool throwExceptions = false) - { - //ensure we have a valid user first! - if (!AuthorizeRequest(throwExceptions)) return false; - - //if it is empty, don't validate - if (app.IsNullOrWhiteSpace()) - { - return true; - } - var hasAccess = UserHasAppAccess(app, Security.CurrentUser); - if (!hasAccess && throwExceptions) - throw new SecurityException("The user does not have access to the required application"); - return hasAccess; - } - - /// - /// Checks if the specified user as access to the app - /// - /// - /// - /// - protected bool UserHasAppAccess(string app, IUser user) - { - return Security.UserHasSectionAccess(app, user); - } - - /// - /// Checks if the specified user by username as access to the app - /// - /// - /// - /// - protected bool UserHasAppAccess(string app, string username) - { - return Security.UserHasSectionAccess(app, username); - } - - /// - /// Returns true if there is a valid logged in user and that ssl is enabled if required - /// - /// true if an exception should be thrown if authorization fails - /// - protected bool AuthorizeRequest(bool throwExceptions = false) - { - var result = Security.AuthorizeRequest(throwExceptions); - return result == ValidateRequestAttempt.Success; - } - - - } -} +using System; +using System.Security; +using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Web.Security; +using Umbraco.Core.Models.Membership; +using Umbraco.Core.Services; + +namespace Umbraco.Web +{ + public abstract class UmbracoAuthorizedHttpHandler : UmbracoHttpHandler + { + protected UmbracoAuthorizedHttpHandler() + { } + + protected UmbracoAuthorizedHttpHandler(UmbracoContext umbracoContext, ServiceContext services, CacheHelper appCache) + : base(umbracoContext, services, appCache) + { + } + + private bool _hasValidated = false; + + /// + /// Checks if the umbraco context id is valid + /// + /// + /// + protected bool ValidateUserContextId(string currentUmbracoUserContextId) + { + return UmbracoContext.Security.ValidateCurrentUser(); + } + + /// + /// Checks if the username/password credentials are valid + /// + /// + /// + /// + protected bool ValidateCredentials(string username, string password) + { + return UmbracoContext.Security.ValidateBackOfficeCredentials(username, password); + } + + /// + /// Validates the user for access to a certain application + /// + /// The application alias. + /// true if an exception should be thrown if authorization fails + /// + protected bool AuthorizeRequest(string app, bool throwExceptions = false) + { + //ensure we have a valid user first! + if (!AuthorizeRequest(throwExceptions)) return false; + + //if it is empty, don't validate + if (app.IsNullOrWhiteSpace()) + { + return true; + } + var hasAccess = UserHasAppAccess(app, Security.CurrentUser); + if (!hasAccess && throwExceptions) + throw new SecurityException("The user does not have access to the required application"); + return hasAccess; + } + + /// + /// Checks if the specified user as access to the app + /// + /// + /// + /// + protected bool UserHasAppAccess(string app, IUser user) + { + return Security.UserHasSectionAccess(app, user); + } + + /// + /// Checks if the specified user by username as access to the app + /// + /// + /// + /// + protected bool UserHasAppAccess(string app, string username) + { + return Security.UserHasSectionAccess(app, username); + } + + /// + /// Returns true if there is a valid logged in user and that ssl is enabled if required + /// + /// true if an exception should be thrown if authorization fails + /// + protected bool AuthorizeRequest(bool throwExceptions = false) + { + var result = Security.AuthorizeRequest(throwExceptions); + return result == ValidateRequestAttempt.Success; + } + + + } +} diff --git a/src/Umbraco.Web/WebServices/UmbracoHttpHandler.cs b/src/Umbraco.Web/UmbracoHttpHandler.cs similarity index 95% rename from src/Umbraco.Web/WebServices/UmbracoHttpHandler.cs rename to src/Umbraco.Web/UmbracoHttpHandler.cs index 200f482cac..e64c4c5fe1 100644 --- a/src/Umbraco.Web/WebServices/UmbracoHttpHandler.cs +++ b/src/Umbraco.Web/UmbracoHttpHandler.cs @@ -1,75 +1,75 @@ -using System; -using System.Web; -using System.Web.Mvc; -using System.Web.Routing; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Logging; -using Umbraco.Core.Persistence; -using Umbraco.Core.Services; -using Umbraco.Web.Composing; -using Umbraco.Web.Security; - -namespace Umbraco.Web.WebServices -{ - public abstract class UmbracoHttpHandler : IHttpHandler - { - private UrlHelper _url; - - protected UmbracoHttpHandler() - : this(Current.UmbracoContext, Current.Services, Current.ApplicationCache) - { } - - protected UmbracoHttpHandler(UmbracoContext umbracoContext, ServiceContext services, CacheHelper appCache) - { - if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext)); - UmbracoContext = umbracoContext; - Umbraco = new UmbracoHelper(umbracoContext, services, appCache); - - // fixme inject somehow - Logger = Current.Logger; - ProfilingLogger = Current.ProfilingLogger; - Services = Current.Services; - } - - public abstract void ProcessRequest(HttpContext context); - - public abstract bool IsReusable { get; } - - /// - /// Gets the logger. - /// - public ILogger Logger { get; } - - /// - /// Gets the ProfilingLogger. - /// - public ProfilingLogger ProfilingLogger { get; } - - /// - /// Gets the Umbraco context. - /// - public UmbracoContext UmbracoContext { get; } - - /// - /// Gets the Umbraco helper. - /// - public UmbracoHelper Umbraco { get; } - - /// - /// Gets the services context. - /// - public ServiceContext Services { get; } - - /// - /// Gets the web security helper. - /// - public WebSecurity Security => UmbracoContext.Security; - - /// - /// Gets the Url helper. - /// - /// This URL helper is created without any route data and an empty request context. - public UrlHelper Url => _url ?? (_url = new UrlHelper(HttpContext.Current.Request.RequestContext)); - } -} +using System; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; +using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence; +using Umbraco.Core.Services; +using Umbraco.Web.Composing; +using Umbraco.Web.Security; + +namespace Umbraco.Web +{ + public abstract class UmbracoHttpHandler : IHttpHandler + { + private UrlHelper _url; + + protected UmbracoHttpHandler() + : this(Current.UmbracoContext, Current.Services, Current.ApplicationCache) + { } + + protected UmbracoHttpHandler(UmbracoContext umbracoContext, ServiceContext services, CacheHelper appCache) + { + if (umbracoContext == null) throw new ArgumentNullException(nameof(umbracoContext)); + UmbracoContext = umbracoContext; + Umbraco = new UmbracoHelper(umbracoContext, services, appCache); + + // fixme inject somehow + Logger = Current.Logger; + ProfilingLogger = Current.ProfilingLogger; + Services = Current.Services; + } + + public abstract void ProcessRequest(HttpContext context); + + public abstract bool IsReusable { get; } + + /// + /// Gets the logger. + /// + public ILogger Logger { get; } + + /// + /// Gets the ProfilingLogger. + /// + public ProfilingLogger ProfilingLogger { get; } + + /// + /// Gets the Umbraco context. + /// + public UmbracoContext UmbracoContext { get; } + + /// + /// Gets the Umbraco helper. + /// + public UmbracoHelper Umbraco { get; } + + /// + /// Gets the services context. + /// + public ServiceContext Services { get; } + + /// + /// Gets the web security helper. + /// + public WebSecurity Security => UmbracoContext.Security; + + /// + /// Gets the Url helper. + /// + /// This URL helper is created without any route data and an empty request context. + public UrlHelper Url => _url ?? (_url = new UrlHelper(HttpContext.Current.Request.RequestContext)); + } +} diff --git a/src/Umbraco.Web/WebServices/UmbracoWebService.cs b/src/Umbraco.Web/UmbracoWebService.cs similarity index 95% rename from src/Umbraco.Web/WebServices/UmbracoWebService.cs rename to src/Umbraco.Web/UmbracoWebService.cs index 4eb7293f80..20db7208b5 100644 --- a/src/Umbraco.Web/WebServices/UmbracoWebService.cs +++ b/src/Umbraco.Web/UmbracoWebService.cs @@ -1,76 +1,76 @@ -using System; -using System.Web; -using System.Web.Mvc; -using System.Web.Routing; -using System.Web.Services; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; -using Umbraco.Core.Persistence; -using Umbraco.Core.Services; -using Umbraco.Web.Composing; -using Umbraco.Web.Security; - -namespace Umbraco.Web.WebServices -{ - /// - /// An abstract web service class exposing common umbraco objects - /// - public abstract class UmbracoWebService : WebService - { - private UrlHelper _url; - - protected UmbracoWebService() - { - UmbracoContext = Current.UmbracoContext; - Umbraco = new UmbracoHelper(UmbracoContext, Current.Services, Current.ApplicationCache); - - Logger = Current.Logger; - ProfilingLogger = Current.ProfilingLogger; - Services = Current.Services; - GlobalSettings = UmbracoConfig.For.GlobalSettings(); - } - - /// - /// Gets the logger. - /// - public ILogger Logger { get; } - - /// - /// Gets the ProfilingLogger. - /// - public ProfilingLogger ProfilingLogger { get; } - - /// - /// Gets the Umbraco context. - /// - public UmbracoContext UmbracoContext { get; } - - /// - /// Gets the Umbraco helper. - /// - public UmbracoHelper Umbraco { get; } - - /// - /// Gets the services context. - /// - public ServiceContext Services { get; } - - /// - /// Gets the global settings. - /// - public IGlobalSettings GlobalSettings { get; } - - /// - /// Gets the web security helper. - /// - public WebSecurity Security => UmbracoContext.Security; - - /// - /// Gets the Url helper. - /// - /// This URL helper is created without any route data and an empty request context. - public UrlHelper Url => _url ?? (_url = new UrlHelper(Context.Request.RequestContext)); - } -} +using System; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; +using System.Web.Services; +using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Configuration; +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence; +using Umbraco.Core.Services; +using Umbraco.Web.Composing; +using Umbraco.Web.Security; + +namespace Umbraco.Web +{ + /// + /// An abstract web service class exposing common umbraco objects + /// + public abstract class UmbracoWebService : WebService + { + private UrlHelper _url; + + protected UmbracoWebService() + { + UmbracoContext = Current.UmbracoContext; + Umbraco = new UmbracoHelper(UmbracoContext, Current.Services, Current.ApplicationCache); + + Logger = Current.Logger; + ProfilingLogger = Current.ProfilingLogger; + Services = Current.Services; + GlobalSettings = UmbracoConfig.For.GlobalSettings(); + } + + /// + /// Gets the logger. + /// + public ILogger Logger { get; } + + /// + /// Gets the ProfilingLogger. + /// + public ProfilingLogger ProfilingLogger { get; } + + /// + /// Gets the Umbraco context. + /// + public UmbracoContext UmbracoContext { get; } + + /// + /// Gets the Umbraco helper. + /// + public UmbracoHelper Umbraco { get; } + + /// + /// Gets the services context. + /// + public ServiceContext Services { get; } + + /// + /// Gets the global settings. + /// + public IGlobalSettings GlobalSettings { get; } + + /// + /// Gets the web security helper. + /// + public WebSecurity Security => UmbracoContext.Security; + + /// + /// Gets the Url helper. + /// + /// This URL helper is created without any route data and an empty request context. + public UrlHelper Url => _url ?? (_url = new UrlHelper(Context.Request.RequestContext)); + } +} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Tree/CustomTreeService.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Tree/CustomTreeService.cs index f3143bad30..b8f4506cb1 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Tree/CustomTreeService.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Tree/CustomTreeService.cs @@ -11,6 +11,7 @@ using umbraco.cms.businesslogic; using umbraco.cms.presentation.Trees; using umbraco.controls.Tree; using Umbraco.Core.Services; +using Umbraco.Web; using Umbraco.Web.Security; using Umbraco.Web.WebServices; diff --git a/src/Umbraco.Web/WebServices/UmbracoAuthorizedWebService.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/UmbracoAuthorizedWebService.cs similarity index 96% rename from src/Umbraco.Web/WebServices/UmbracoAuthorizedWebService.cs rename to src/Umbraco.Web/umbraco.presentation/umbraco/webservices/UmbracoAuthorizedWebService.cs index a48d3ef421..33c4831c40 100644 --- a/src/Umbraco.Web/WebServices/UmbracoAuthorizedWebService.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/UmbracoAuthorizedWebService.cs @@ -1,95 +1,97 @@ -using System; -using System.Security; -using Umbraco.Web.Security; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Models.Membership; -using Umbraco.Core.Services; - -namespace Umbraco.Web.WebServices -{ - /// - /// An abstract web service class that has the methods and properties to correct validate an Umbraco user - /// - public abstract class UmbracoAuthorizedWebService : UmbracoWebService - { - private bool _hasValidated = false; - - /// - /// Checks if the umbraco context id is valid - /// - /// - /// - protected bool ValidateUserContextId(string currentUmbracoUserContextId) - { - return UmbracoContext.Security.ValidateCurrentUser(); - } - - /// - /// Checks if the username/password credentials are valid - /// - /// - /// - /// - protected bool ValidateCredentials(string username, string password) - { - return UmbracoContext.Security.ValidateBackOfficeCredentials(username, password); - } - - /// - /// Validates the user for access to a certain application - /// - /// The application alias. - /// true if an exception should be thrown if authorization fails - /// - protected bool AuthorizeRequest(string app, bool throwExceptions = false) - { - //ensure we have a valid user first! - if (!AuthorizeRequest(throwExceptions)) return false; - - //if it is empty, don't validate - if (app.IsNullOrWhiteSpace()) - { - return true; - } - var hasAccess = UserHasAppAccess(app, Security.CurrentUser); - if (!hasAccess && throwExceptions) - throw new SecurityException("The user does not have access to the required application"); - return hasAccess; - } - - /// - /// Checks if the specified user as access to the app - /// - /// - /// - /// - protected bool UserHasAppAccess(string app, IUser user) - { - return Security.UserHasSectionAccess(app, user); - } - - /// - /// Checks if the specified user by username as access to the app - /// - /// - /// - /// - protected bool UserHasAppAccess(string app, string username) - { - return Security.UserHasSectionAccess(app, username); - } - - /// - /// Returns true if there is a valid logged in user and that ssl is enabled if required - /// - /// true if an exception should be thrown if authorization fails - /// - protected bool AuthorizeRequest(bool throwExceptions = false) - { - var result = Security.AuthorizeRequest(throwExceptions); - return result == ValidateRequestAttempt.Success; - } - - } -} +using System; +using System.Security; +using Umbraco.Web.Security; +using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Models.Membership; +using Umbraco.Core.Services; +using Umbraco.Web; +using Umbraco.Web.WebServices; + +namespace umbraco.presentation.webservices +{ + /// + /// An abstract web service class that has the methods and properties to correct validate an Umbraco user + /// + public abstract class UmbracoAuthorizedWebService : UmbracoWebService + { + private bool _hasValidated = false; + + /// + /// Checks if the umbraco context id is valid + /// + /// + /// + protected bool ValidateUserContextId(string currentUmbracoUserContextId) + { + return UmbracoContext.Security.ValidateCurrentUser(); + } + + /// + /// Checks if the username/password credentials are valid + /// + /// + /// + /// + protected bool ValidateCredentials(string username, string password) + { + return UmbracoContext.Security.ValidateBackOfficeCredentials(username, password); + } + + /// + /// Validates the user for access to a certain application + /// + /// The application alias. + /// true if an exception should be thrown if authorization fails + /// + protected bool AuthorizeRequest(string app, bool throwExceptions = false) + { + //ensure we have a valid user first! + if (!AuthorizeRequest(throwExceptions)) return false; + + //if it is empty, don't validate + if (app.IsNullOrWhiteSpace()) + { + return true; + } + var hasAccess = UserHasAppAccess(app, Security.CurrentUser); + if (!hasAccess && throwExceptions) + throw new SecurityException("The user does not have access to the required application"); + return hasAccess; + } + + /// + /// Checks if the specified user as access to the app + /// + /// + /// + /// + protected bool UserHasAppAccess(string app, IUser user) + { + return Security.UserHasSectionAccess(app, user); + } + + /// + /// Checks if the specified user by username as access to the app + /// + /// + /// + /// + protected bool UserHasAppAccess(string app, string username) + { + return Security.UserHasSectionAccess(app, username); + } + + /// + /// Returns true if there is a valid logged in user and that ssl is enabled if required + /// + /// true if an exception should be thrown if authorization fails + /// + protected bool AuthorizeRequest(bool throwExceptions = false) + { + var result = Security.AuthorizeRequest(throwExceptions); + return result == ValidateRequestAttempt.Success; + } + + } +} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs index 1fa387757e..80643e85aa 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/nodeSorter.asmx.cs @@ -10,7 +10,6 @@ using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Web; using Umbraco.Web.Composing; -using Umbraco.Web.WebServices; using Umbraco.Web._Legacy.Actions; namespace umbraco.presentation.webservices From c0b094f2e8640c44bccebfe453fc18484831a3ec Mon Sep 17 00:00:00 2001 From: Russell Date: Wed, 27 Jun 2018 10:06:45 +1200 Subject: [PATCH 024/134] Fix http://issues.umbraco.org/issue/U4-8887 The only usage of __mcenew id is to change the HTML when there is size set on the element. This is done on the timeout function. As per suggestion - "we wipe the ID in $timeout then, regardless the maxSize" --- .../src/common/services/tinymce.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 86de5b586d..7e97d83fa2 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -154,13 +154,13 @@ function tinyMceService(dialogService, $log, imageHelper, $http, $timeout, macro var s = "width: " + newSize.width + "px; height:" + newSize.height + "px;"; editor.dom.setAttrib(imgElm, 'style', s); - editor.dom.setAttrib(imgElm, 'id', null); if (img.url) { var src = img.url + "?width=" + newSize.width + "&height=" + newSize.height; editor.dom.setAttrib(imgElm, 'data-mce-src', src); } } + editor.dom.setAttrib(imgElm, 'id', null); }, 500); } }, From 774227314e7cbccecfe6f8e43d67997db51bf7c5 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 27 Jun 2018 14:09:30 +0200 Subject: [PATCH 025/134] Fix Media library thumbnail does not reload if a new image with the same name is uploaded --- .../views/propertyeditors/fileupload/fileupload.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js index 2a66ee457b..ba9e868962 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js @@ -73,7 +73,7 @@ function fileUploadController($scope, $element, $compile, imageHelper, fileManag var extension = file.file.substring(file.file.lastIndexOf(".") + 1, file.file.length); - file.thumbnail = thumbnailUrl; + file.thumbnail = thumbnailUrl + '&rnd=' + Math.random(); file.extension = extension.toLowerCase(); }); From 80412f56eeab57ba4fb21b27e286e48fb91f64bf Mon Sep 17 00:00:00 2001 From: Dan Patching Date: Sun, 8 Jul 2018 14:15:27 +0100 Subject: [PATCH 026/134] enable use of radiobuttonlist pre editor --- src/Umbraco.Core/Models/PreValueInnerListItem.cs | 13 +++++++++++++ src/Umbraco.Core/PropertyEditors/PreValueField.cs | 9 ++++++++- src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../src/common/services/datatypehelper.service.js | 3 ++- .../src/views/datatypes/datatype.edit.controller.js | 1 + .../Models/ContentEditing/PreValueFieldDisplay.cs | 8 +++++++- 6 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 src/Umbraco.Core/Models/PreValueInnerListItem.cs diff --git a/src/Umbraco.Core/Models/PreValueInnerListItem.cs b/src/Umbraco.Core/Models/PreValueInnerListItem.cs new file mode 100644 index 0000000000..d4480d56d3 --- /dev/null +++ b/src/Umbraco.Core/Models/PreValueInnerListItem.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace Umbraco.Core.Models +{ + public class PreValueInnerListItem + { + [JsonProperty("value")] + public object Value { get; set; } + + [JsonProperty("label")] + public string Label { get; set; } + } +} diff --git a/src/Umbraco.Core/PropertyEditors/PreValueField.cs b/src/Umbraco.Core/PropertyEditors/PreValueField.cs index 2b66f7a6a8..144333e449 100644 --- a/src/Umbraco.Core/PropertyEditors/PreValueField.cs +++ b/src/Umbraco.Core/PropertyEditors/PreValueField.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Newtonsoft.Json; using Umbraco.Core.Manifest; +using Umbraco.Core.Models; namespace Umbraco.Core.PropertyEditors { @@ -86,5 +87,11 @@ namespace Umbraco.Core.PropertyEditors /// [JsonProperty("config")] public IDictionary Config { get; set; } + + /// + /// This allows for inner prevalues to be defined, for views such as radiobuttonlist, that require a selection. + /// + [JsonProperty("prevalues")] + public PreValueInnerListItem[] PreValues { get; set; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 0f5461eb35..337fad89dc 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -386,6 +386,7 @@ + diff --git a/src/Umbraco.Web.UI.Client/src/common/services/datatypehelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/datatypehelper.service.js index 3cde632d4b..264d15215f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/datatypehelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/datatypehelper.service.js @@ -18,7 +18,8 @@ function dataTypeHelper() { description: preVals[i].description, label: preVals[i].label, view: preVals[i].view, - value: preVals[i].value + value: preVals[i].value, + prevalues: preVals[i].prevalues }); } diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.edit.controller.js index ad15167d18..329acc86f0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.edit.controller.js @@ -29,6 +29,7 @@ function DataTypeEditController($scope, $routeParams, $location, appState, navig view: preVals[i].view, value: preVals[i].value, config: preVals[i].config, + prevalues: preVals[i].prevalues }); } } diff --git a/src/Umbraco.Web/Models/ContentEditing/PreValueFieldDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/PreValueFieldDisplay.cs index 6879701bde..bd1624e0b5 100644 --- a/src/Umbraco.Web/Models/ContentEditing/PreValueFieldDisplay.cs +++ b/src/Umbraco.Web/Models/ContentEditing/PreValueFieldDisplay.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Runtime.Serialization; +using Umbraco.Core.Models; namespace Umbraco.Web.Models.ContentEditing { @@ -40,5 +41,10 @@ namespace Umbraco.Web.Models.ContentEditing [DataMember(Name = "config")] public IDictionary Config { get; set; } + /// + /// This allows for inner prevalues to be defined, for views such as radiobuttonlist, that require a selection. + /// + [DataMember(Name = "prevalues")] + public PreValueInnerListItem[] PreValues { get; set; } } -} \ No newline at end of file +} From 229e6dd043a1a5a8807efcc1b5a48493a7b5a52a Mon Sep 17 00:00:00 2001 From: Tim Payne Date: Thu, 12 Jul 2018 13:51:05 +0100 Subject: [PATCH 027/134] Retarget for 7.12.0 --- .../TargetVersionSevenEightZero/RenameTrueFalseField.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenEightZero/RenameTrueFalseField.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenEightZero/RenameTrueFalseField.cs index b425086502..2f2c1fbfc6 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenEightZero/RenameTrueFalseField.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenEightZero/RenameTrueFalseField.cs @@ -6,7 +6,7 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenEightZero { - [MigrationAttribute("7.8.0", 0, Constants.System.UmbracoMigrationName)] + [MigrationAttribute("7.12.0", 0, Constants.System.UmbracoMigrationName)] public class RenameTrueFalseField : MigrationBase { public RenameTrueFalseField(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger) From 129621440096674a014fec36c0768726380340dc Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sun, 15 Jul 2018 20:20:57 +0200 Subject: [PATCH 028/134] Localization of text in color picker --- .../colorpicker/multicolorpicker.controller.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js index 98e649729c..e0e744062b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js @@ -1,5 +1,5 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.MultiColorPickerController", - function ($scope, $timeout, assetsService, angularHelper, $element) { + function ($scope, $timeout, assetsService, angularHelper, $element, localizationService) { //NOTE: We need to make each color an object, not just a string because you cannot 2-way bind to a primitive. var defaultColor = "000000"; var defaultLabel = null; @@ -8,6 +8,18 @@ $scope.newLavel = defaultLabel; $scope.hasError = false; + $scope.labels = {}; + + var labelKeys = [ + "general_cancel", + "general_choose" + ]; + + localizationService.localizeMany(labelKeys).then(function (values) { + $scope.labels.cancel = values[0]; + $scope.labels.choose = values[1]; + }); + assetsService.load([ //"lib/spectrum/tinycolor.js", "lib/spectrum/spectrum.js" @@ -16,8 +28,8 @@ elem.spectrum({ color: null, showInitial: false, - chooseText: "choose", // TODO: These can be localised - cancelText: "cancel", // TODO: These can be localised + chooseText: $scope.labels.choose, + cancelText: $scope.labels.cancel, preferredFormat: "hex", showInput: true, clickoutFiresChange: true, From d697e46f249c2a85794d5d43c98af838ff8de9a0 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sun, 15 Jul 2018 20:22:12 +0200 Subject: [PATCH 029/134] Configurate sortable on color picker property editor --- .../src/less/property-editors.less | 27 +++++-------- .../colorpicker/colorpicker.controller.js | 38 +++++++++++++++++++ .../colorpicker/colorpicker.prevalues.html | 13 ++++--- .../multicolorpicker.controller.js | 37 ++++++++++++++++++ 4 files changed, 92 insertions(+), 23 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index dd0e4d3e77..5dc4b8658f 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -154,47 +154,38 @@ ul.color-picker li a { } /* pre-value editor */ -/*.control-group.color-picker-preval:before { - content: ""; +.control-group.color-picker-preval .handle { + float: left; display: inline-block; - vertical-align: middle; - height: 100%; -}*/ - -/*.control-group.color-picker-preval div.thumbnail { - display: inline-block; - vertical-align: middle; -}*/ + margin: 5px 3px 5px 0; +} .control-group.color-picker-preval div.color-picker-prediv { display: inline-block; - width: 60%; + width: 50%; } .control-group.color-picker-preval pre { display: inline; - margin-right: 20px; + margin-right: 10px; margin-left: 10px; width: 50%; white-space: nowrap; overflow: hidden; margin-bottom: 0; vertical-align: middle; -} - -.control-group.color-picker-preval btn { - //vertical-align: middle; + padding-top: 7px; + padding-bottom: 7px; } .control-group.color-picker-preval input[type="text"] { min-width: 40%; width: 40%; display: inline-block; - margin-right: 20px; margin-top: 1px; } .control-group.color-picker-preval label { - border: solid @white 1px; + border: 1px solid @white; padding: 6px; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js index 5230f9ef2c..03defbc930 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js @@ -1,5 +1,41 @@ function ColorPickerController($scope) { + //setup the default config + var config = { + items: [], + multiple: false + }; + + //map the user config + angular.extend(config, $scope.model.config); + + //map back to the model + $scope.model.config = config; + + function convertArrayToDictionaryArray(model) { + //now we need to format the items in the dictionary because we always want to have an array + var newItems = []; + for (var i = 0; i < model.length; i++) { + newItems.push({ id: model[i], sortOrder: 0, value: model[i] }); + } + + return newItems; + } + + + function convertObjectToDictionaryArray(model) { + //now we need to format the items in the dictionary because we always want to have an array + var newItems = []; + var vals = _.values($scope.model.config.items); + var keys = _.keys($scope.model.config.items); + + for (var i = 0; i < vals.length; i++) { + var label = vals[i].value ? vals[i].value : vals[i]; + newItems.push({ id: keys[i], sortOrder: vals[i].sortOrder, value: label }); + } + + return newItems; + } $scope.isConfigured = $scope.model.config && $scope.model.config.items && _.keys($scope.model.config.items).length > 0; if ($scope.isConfigured) { @@ -13,6 +49,8 @@ function ColorPickerController($scope) { initActiveColor(); } + //sort the values + $scope.model.config.items.sort(function (a, b) { return (a.sortOrder > b.sortOrder) ? 1 : ((b.sortOrder > a.sortOrder) ? -1 : 0); }); $scope.toggleItem = function (color) { var currentColor = ($scope.model.value && $scope.model.value.hasOwnProperty("value")) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html index 2b917e69f8..2d342c92fc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html @@ -1,13 +1,16 @@
- +
-
-
-
#{{item.value}} - {{item.label}}
- +
+
+ +
+
#{{item.value}}
{{item.label}}
+ +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js index e0e744062b..3751117485 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js @@ -68,6 +68,10 @@ }); } } + + //ensure the items are sorted by the provided sort order + items.sort(function (a, b) { return (a.sortOrder > b.sortOrder) ? 1 : ((b.sortOrder > a.sortOrder) ? -1 : 0); }); + //now make the editor model the array $scope.model.value = items; } @@ -116,6 +120,39 @@ }; + $scope.sortableOptions = { + axis: 'y', + containment: 'parent', + cursor: 'move', + handle: ".handle, .thumbnail", + items: '> div.control-group', + tolerance: 'pointer', + update: function (e, ui) { + // Get the new and old index for the moved element (using the text as the identifier, so + // we'd have a problem if two prevalues were the same, but that would be unlikely) + var newIndex = ui.item.index(); + var movedPrevalueText = $('pre', ui.item).text(); + var originalIndex = getElementIndexByPrevalueText(movedPrevalueText); + + //// Move the element in the model + if (originalIndex > -1) { + var movedElement = $scope.model.value[originalIndex]; + $scope.model.value.splice(originalIndex, 1); + $scope.model.value.splice(newIndex, 0, movedElement); + } + } + }; + + function getElementIndexByPrevalueText(value) { + for (var i = 0; i < $scope.model.value.length; i++) { + if ($scope.model.value[i].value === value) { + return i; + } + } + + return -1; + } + //load the separate css for the editor to avoid it blocking our js loading assetsService.loadCss("lib/spectrum/spectrum.css", $scope); }); From 130dabfdce79ff1eee99423fce2984ad680e2c72 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sun, 15 Jul 2018 20:23:54 +0200 Subject: [PATCH 030/134] Add monospace font on pre elements to ensure same width of elements --- src/Umbraco.Web.UI.Client/src/less/property-editors.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 5dc4b8658f..cff7141daa 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -166,6 +166,7 @@ ul.color-picker li a { .control-group.color-picker-preval pre { display: inline; + font-family: monospace; margin-right: 10px; margin-left: 10px; width: 50%; From 912b101d0a10db4f6a286cf53b3f07c2031eb3ab Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sun, 15 Jul 2018 21:44:03 +0200 Subject: [PATCH 031/134] Order items by sort order --- .../PropertyEditors/ColorListPreValueEditor.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs index a504ed0431..8c2a36fe10 100644 --- a/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs @@ -40,9 +40,9 @@ namespace Umbraco.Web.PropertyEditors public override IDictionary ConvertDbToEditor(IDictionary defaultPreVals, PreValueCollection persistedPreVals) { var dictionary = persistedPreVals.FormatAsDictionary(); - var items = dictionary - .Where(x => x.Key != "useLabel") - .ToDictionary(x => x.Value.Id, x => x.Value.Value); + var items = dictionary.Where(x => x.Key != "useLabel") + .OrderBy(x => x.Value.SortOrder) + .ToDictionary(x => x.Value.Id, x => x.Value.Value); var items2 = new Dictionary(); foreach (var item in items) @@ -150,4 +150,4 @@ namespace Umbraco.Web.PropertyEditors } } } -} \ No newline at end of file +} From ec78e99ca0583a09b3c7c59636b460038b1f57fc Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sun, 15 Jul 2018 22:07:06 +0200 Subject: [PATCH 032/134] Add sortorder to prevalue --- .../PropertyEditors/ColorListPreValueEditor.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs index 8c2a36fe10..dc949c2dd7 100644 --- a/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs @@ -95,16 +95,20 @@ namespace Umbraco.Web.PropertyEditors .Select(x => { var idString = x["id"] == null ? "0" : x["id"].ToString(); - int id; - if (int.TryParse(idString, out id) == false) id = 0; + int id = int.TryParse(idString, out id) ? id : 0; var color = x["value"].ToString(); if (string.IsNullOrWhiteSpace(color)) return null; var label = x["label"].ToString(); - return new PreValue(id, useLabel - ? JsonConvert.SerializeObject(new { value = color, label = label }) - : color); + + int.TryParse(x["sortOrder"]?.ToString(), out var sortOrder); + + var value = useLabel + ? JsonConvert.SerializeObject(new { value = color, label = label, sortOrder = sortOrder }) + : color; + + return new PreValue(id, value, sortOrder); }) .WhereNotNull()) { From 6ac654a36b2f8fcc84962560e7e18316926d2cda Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sun, 15 Jul 2018 22:21:55 +0200 Subject: [PATCH 033/134] Add different cursor styling on sortable thumbnail handle --- src/Umbraco.Web.UI.Client/src/less/property-editors.less | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index cff7141daa..c70688d935 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -149,8 +149,9 @@ ul.color-picker li a { } .control-group.color-picker-preval .thumbnail { - width:30px; - border:none; + width: 30px; + border: none; + cursor: move; } /* pre-value editor */ From 565c9ef95d833bf8eb72c9f5a6b0fc273f733352 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 16 Jul 2018 11:41:10 +0200 Subject: [PATCH 034/134] Cleans up some code and fixes sorting / storing the correct order. --- .../PropertyEditors/ColorListPreValueEditor.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs index dc949c2dd7..da286e8260 100644 --- a/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs @@ -80,30 +80,30 @@ namespace Umbraco.Web.PropertyEditors try { - object useLabelObj; var useLabel = false; - if (editorValue.TryGetValue("useLabel", out useLabelObj)) + if (editorValue.TryGetValue("useLabel", out var useLabelObj)) { - useLabel = useLabelObj is string && (string) useLabelObj == "1"; + useLabel = useLabelObj is string && (string)useLabelObj == "1"; result["useLabel"] = new PreValue(useLabel ? "1" : "0"); } // get all non-empty values var index = 0; + // we don't get the actual sortOrder but items get submitted in the sorted order, so let's just count them up + var sortOrder = -1; foreach (var preValue in val.OfType() .Where(x => x["value"] != null) .Select(x => { var idString = x["id"] == null ? "0" : x["id"].ToString(); - int id = int.TryParse(idString, out id) ? id : 0; + int.TryParse(idString, out var id); var color = x["value"].ToString(); if (string.IsNullOrWhiteSpace(color)) return null; var label = x["label"].ToString(); - int.TryParse(x["sortOrder"]?.ToString(), out var sortOrder); - + sortOrder++; var value = useLabel ? JsonConvert.SerializeObject(new { value = color, label = label, sortOrder = sortOrder }) : color; From 157b66dc4c1055702ef8ef1b16836f33f796f010 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 16 Jul 2018 18:08:20 +0200 Subject: [PATCH 035/134] Fixes the persistence and correct display of the sort order --- .../colorpicker/colorpicker.controller.js | 331 ++++++++++-------- .../multicolorpicker.controller.js | 2 + .../ColorListPreValueEditor.cs | 70 ++-- 3 files changed, 229 insertions(+), 174 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js index 03defbc930..abb26ef4a2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js @@ -1,84 +1,111 @@ -function ColorPickerController($scope) { - - //setup the default config - var config = { - items: [], - multiple: false - }; - - //map the user config - angular.extend(config, $scope.model.config); - - //map back to the model - $scope.model.config = config; - - function convertArrayToDictionaryArray(model) { - //now we need to format the items in the dictionary because we always want to have an array - var newItems = []; - for (var i = 0; i < model.length; i++) { - newItems.push({ id: model[i], sortOrder: 0, value: model[i] }); - } - - return newItems; - } - - - function convertObjectToDictionaryArray(model) { - //now we need to format the items in the dictionary because we always want to have an array - var newItems = []; - var vals = _.values($scope.model.config.items); - var keys = _.keys($scope.model.config.items); - - for (var i = 0; i < vals.length; i++) { - var label = vals[i].value ? vals[i].value : vals[i]; - newItems.push({ id: keys[i], sortOrder: vals[i].sortOrder, value: label }); - } - - return newItems; - } - $scope.isConfigured = $scope.model.config && $scope.model.config.items && _.keys($scope.model.config.items).length > 0; - - if ($scope.isConfigured) { - - for (var key in $scope.model.config.items) { - if (!$scope.model.config.items[key].hasOwnProperty("value")) - $scope.model.config.items[key] = { value: $scope.model.config.items[key], label: $scope.model.config.items[key] }; - } - - $scope.model.useLabel = isTrue($scope.model.config.useLabel); - initActiveColor(); - } +function ColorPickerController($scope) { + + //setup the default config + var config = { + items: [], + multiple: false + }; + + //map the user config + angular.extend(config, $scope.model.config); + + //map back to the model + $scope.model.config = config; + + function convertArrayToDictionaryArray(model) { + //now we need to format the items in the dictionary because we always want to have an array + var newItems = []; + for (var i = 0; i < model.length; i++) { + newItems.push({ id: model[i], sortOrder: 0, value: model[i] }); + } + + return newItems; + } + + + function convertObjectToDictionaryArray(model) { + //now we need to format the items in the dictionary because we always want to have an array + var newItems = []; + var vals = _.values($scope.model.config.items); + var keys = _.keys($scope.model.config.items); + + for (var i = 0; i < vals.length; i++) { + var label = vals[i].value ? vals[i].value : vals[i]; + newItems.push({ id: keys[i], sortOrder: vals[i].sortOrder, value: label }); + } + + return newItems; + } + $scope.isConfigured = $scope.model.config && $scope.model.config.items && _.keys($scope.model.config.items).length > 0; + + if ($scope.isConfigured) { + + for (var key in $scope.model.config.items) { + if (!$scope.model.config.items[key].hasOwnProperty("value")) + $scope.model.config.items[key] = { value: $scope.model.config.items[key], label: $scope.model.config.items[key] }; + } + + $scope.model.useLabel = isTrue($scope.model.config.useLabel); + initActiveColor(); + } + + if (!angular.isArray($scope.model.config.items)) { + //make an array from the dictionary + var items = []; + for (var i in $scope.model.config.items) { + var oldValue = $scope.model.config.items[i]; + if (oldValue.hasOwnProperty("value")) { + items.push({ + value: oldValue.value, + label: oldValue.label, + sortOrder: oldValue.sortOrder, + id: i + }); + } else { + items.push({ + value: oldValue, + label: oldValue, + sortOrder: sortOrder, + id: i + }); + } + } + + //ensure the items are sorted by the provided sort order + items.sort(function (a, b) { return (a.sortOrder > b.sortOrder) ? 1 : ((b.sortOrder > a.sortOrder) ? -1 : 0); }); + + //now make the editor model the array + $scope.model.config.items = items; + } + + $scope.toggleItem = function (color) { + + var currentColor = ($scope.model.value && $scope.model.value.hasOwnProperty("value")) + ? $scope.model.value.value + : $scope.model.value; - //sort the values - $scope.model.config.items.sort(function (a, b) { return (a.sortOrder > b.sortOrder) ? 1 : ((b.sortOrder > a.sortOrder) ? -1 : 0); }); - $scope.toggleItem = function (color) { - - var currentColor = ($scope.model.value && $scope.model.value.hasOwnProperty("value")) - ? $scope.model.value.value - : $scope.model.value; - var newColor; - if (currentColor === color.value) { - // deselect - $scope.model.value = $scope.model.useLabel ? { value: "", label: "" } : ""; - newColor = ""; - } - else { + if (currentColor === color.value) { + // deselect + $scope.model.value = $scope.model.useLabel ? { value: "", label: "" } : ""; + newColor = ""; + } + else { // select - $scope.model.value = $scope.model.useLabel ? { value: color.value, label: color.label } : color.value; + $scope.model.value = $scope.model.useLabel ? { value: color.value, label: color.label } : color.value; newColor = color.value; - } - - // this is required to re-validate - $scope.propertyForm.modelValue.$setViewValue(newColor); - }; + } + + // this is required to re-validate + $scope.propertyForm.modelValue.$setViewValue(newColor); + }; // Method required by the valPropertyValidator directive (returns true if the property editor has at least one color selected) - $scope.validateMandatory = function () { - var isValid = !$scope.model.validation.mandatory || ( - $scope.model.value != null - && $scope.model.value != "" - && (!$scope.model.value.hasOwnProperty("value") || $scope.model.value.value !== "") + $scope.validateMandatory = function () { + var isValid = !$scope.model.validation.mandatory || ( + $scope.model.value != null + && $scope.model.value != "" + && (!$scope.model.value.hasOwnProperty("value") || $scope.model.value.value !== "") ); return { isValid: isValid, @@ -86,83 +113,83 @@ function ColorPickerController($scope) { errorKey: "required" }; } - $scope.isConfigured = $scope.model.config && $scope.model.config.items && _.keys($scope.model.config.items).length > 0; - - // A color is active if it matches the value and label of the model. - // If the model doesn't store the label, ignore the label during the comparison. - $scope.isActiveColor = function (color) { - - // no value - if (!$scope.model.value) - return false; - - // Complex color (value and label)? - if (!$scope.model.value.hasOwnProperty("value")) - return $scope.model.value === color.value; - - return $scope.model.value.value === color.value && $scope.model.value.label === color.label; - }; - - // Finds the color best matching the model's color, - // and sets the model color to that one. This is useful when - // either the value or label was changed on the data type. - function initActiveColor() { - - // no value - if (!$scope.model.value) - return; - - // Complex color (value and label)? - if (!$scope.model.value.hasOwnProperty("value")) - return; - - var modelColor = $scope.model.value.value; - var modelLabel = $scope.model.value.label; - - // Check for a full match or partial match. - var foundItem = null; - - // Look for a fully matching color. - for (var key in $scope.model.config.items) { - var item = $scope.model.config.items[key]; - if (item.value == modelColor && item.label == modelLabel) { - foundItem = item; - break; - } - } - - // Look for a color with a matching value. - if (!foundItem) { - for (var key in $scope.model.config.items) { - var item = $scope.model.config.items[key]; - if (item.value == modelColor) { - foundItem = item; - break; - } - } - } - - // Look for a color with a matching label. - if (!foundItem) { - for (var key in $scope.model.config.items) { - var item = $scope.model.config.items[key]; - if (item.label == modelLabel) { - foundItem = item; - break; - } - } - } - - // If a match was found, set it as the active color. - if (foundItem) { - $scope.model.value.value = foundItem.value; - $scope.model.value.label = foundItem.label; - } - } - - // figures out if a value is trueish enough - function isTrue(bool) { - return !!bool && bool !== "0" && angular.lowercase(bool) !== "false"; + $scope.isConfigured = $scope.model.config && $scope.model.config.items && _.keys($scope.model.config.items).length > 0; + + // A color is active if it matches the value and label of the model. + // If the model doesn't store the label, ignore the label during the comparison. + $scope.isActiveColor = function (color) { + + // no value + if (!$scope.model.value) + return false; + + // Complex color (value and label)? + if (!$scope.model.value.hasOwnProperty("value")) + return $scope.model.value === color.value; + + return $scope.model.value.value === color.value && $scope.model.value.label === color.label; + }; + + // Finds the color best matching the model's color, + // and sets the model color to that one. This is useful when + // either the value or label was changed on the data type. + function initActiveColor() { + + // no value + if (!$scope.model.value) + return; + + // Complex color (value and label)? + if (!$scope.model.value.hasOwnProperty("value")) + return; + + var modelColor = $scope.model.value.value; + var modelLabel = $scope.model.value.label; + + // Check for a full match or partial match. + var foundItem = null; + + // Look for a fully matching color. + for (var key in $scope.model.config.items) { + var item = $scope.model.config.items[key]; + if (item.value == modelColor && item.label == modelLabel) { + foundItem = item; + break; + } + } + + // Look for a color with a matching value. + if (!foundItem) { + for (var key in $scope.model.config.items) { + var item = $scope.model.config.items[key]; + if (item.value == modelColor) { + foundItem = item; + break; + } + } + } + + // Look for a color with a matching label. + if (!foundItem) { + for (var key in $scope.model.config.items) { + var item = $scope.model.config.items[key]; + if (item.label == modelLabel) { + foundItem = item; + break; + } + } + } + + // If a match was found, set it as the active color. + if (foundItem) { + $scope.model.value.value = foundItem.value; + $scope.model.value.label = foundItem.label; + } + } + + // figures out if a value is trueish enough + function isTrue(bool) { + return !!bool && bool !== "0" && angular.lowercase(bool) !== "false"; } } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js index 3751117485..f19fb260f4 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js @@ -58,12 +58,14 @@ items.push({ value: oldValue.value, label: oldValue.label, + sortOrder: oldValue.sortOrder, id: i }); } else { items.push({ value: oldValue, label: oldValue, + sortOrder: sortOrder, id: i }); } diff --git a/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs index da286e8260..20dd3f9ec8 100644 --- a/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs @@ -26,13 +26,13 @@ namespace Umbraco.Web.PropertyEditors //change the label field.Name = "Add color"; //need to have some custom validation happening here - field.Validators.Add(new ColorListValidator()); - + field.Validators.Add(new ColorListValidator()); + Fields.Insert(0, new PreValueField { - Name = "Include labels?", - View = "boolean", - Key = "useLabel", + Name = "Include labels?", + View = "boolean", + Key = "useLabel", Description = "Stores colors as a Json object containing both the color hex string and label, rather than just the hex string." }); } @@ -41,27 +41,43 @@ namespace Umbraco.Web.PropertyEditors { var dictionary = persistedPreVals.FormatAsDictionary(); var items = dictionary.Where(x => x.Key != "useLabel") - .OrderBy(x => x.Value.SortOrder) - .ToDictionary(x => x.Value.Id, x => x.Value.Value); + .OrderBy(x => x.Value.SortOrder); var items2 = new Dictionary(); foreach (var item in items) { - if (item.Value.DetectIsJson() == false) + var valueItem = new ColorPickerColor { - items2[item.Key] = item.Value; - continue; - } + Color = item.Value.Value, + Label = item.Value.Value, + SortOrder = item.Value.SortOrder + }; - try + if (item.Value.Value.DetectIsJson()) { - items2[item.Key] = JsonConvert.DeserializeObject(item.Value); + try + { + var valueObject = JsonConvert.DeserializeObject(item.Value.Value); + valueItem = new ColorPickerColor + { + Color = valueObject.Color, + Label = valueObject.Label, + SortOrder = valueObject.SortOrder + }; + } + catch + { + // let's say parsing Json failed, we'll not do anything, + // we'll just use the valueItem we built in the first place + } } - catch + + items2[item.Value.Id] = new JObject { - // let's say parsing Json failed, so what we have is the string - build json - items2[item.Key] = new JObject { { "color", item.Value }, { "label", item.Value } }; - } + { "value", valueItem.Color }, + { "label", valueItem.Label }, + { "sortOrder", valueItem.SortOrder } + }; } var result = new Dictionary { { "items", items2 } }; @@ -83,13 +99,13 @@ namespace Umbraco.Web.PropertyEditors var useLabel = false; if (editorValue.TryGetValue("useLabel", out var useLabelObj)) { - useLabel = useLabelObj is string && (string)useLabelObj == "1"; + useLabel = useLabelObj is string && (string) useLabelObj == "1"; result["useLabel"] = new PreValue(useLabel ? "1" : "0"); } // get all non-empty values var index = 0; - // we don't get the actual sortOrder but items get submitted in the sorted order, so let's just count them up + // items get submitted in the sorted order, so just count them up var sortOrder = -1; foreach (var preValue in val.OfType() .Where(x => x["value"] != null) @@ -105,10 +121,10 @@ namespace Umbraco.Web.PropertyEditors sortOrder++; var value = useLabel - ? JsonConvert.SerializeObject(new { value = color, label = label, sortOrder = sortOrder }) - : color; + ? JsonConvert.SerializeObject(new { value = color, label = label, sortOrder = sortOrder }) + : color; - return new PreValue(id, value, sortOrder); + return new PreValue(id, value, sortOrder); }) .WhereNotNull()) { @@ -154,4 +170,14 @@ namespace Umbraco.Web.PropertyEditors } } } + + internal class ColorPickerColor + { + [JsonProperty("value")] + public string Color { get; set; } + [JsonProperty("label")] + public string Label { get; set; } + [JsonProperty("sortOrder")] + public int SortOrder { get; set; } + } } From ef897b2d3e520c830f5f138b6770a5d33e682f82 Mon Sep 17 00:00:00 2001 From: Gareth Evans Date: Tue, 17 Jul 2018 12:25:57 +1200 Subject: [PATCH 036/134] Add ~/.well-known to umbracoReservedUrls to support letsencrypt/certifytheweb ootb --- src/Umbraco.Tests/App.config | 2 +- src/Umbraco.Web.UI/web.Template.Debug.config | 4 ++-- src/Umbraco.Web.UI/web.Template.config | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 09fd6b24f3..fa18d5afd1 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -55,7 +55,7 @@ - + diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index e5a1d3f4f9..014fe14329 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -54,7 +54,7 @@ - + @@ -445,4 +445,4 @@ - \ No newline at end of file + diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index ee8d98cae3..608fda2190 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -42,7 +42,7 @@ http://our.umbraco.org/documentation/using-umbraco/config-files/#webconfig --> - + From 1294512ce81e5de7865e3c76e23f5d19f0c1a0d7 Mon Sep 17 00:00:00 2001 From: Nathan Woulfe Date: Wed, 18 Jul 2018 10:06:08 +1000 Subject: [PATCH 037/134] fix cropped icon, resize large to double small icon size --- .../src/less/components/application/umb-drawer.less | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less b/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less index 0fae291e72..abcace794f 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less @@ -55,7 +55,7 @@ /* Our badge - should be moved */ .umb-help-badge { - padding: 10px 20px 10px 35px; + padding: 10px 20px 10px 55px; background: @white; position: relative; overflow: hidden; @@ -74,10 +74,10 @@ } .umb-help-badge__icon { - font-size: 40px; + font-size: 36px; transform: translate(0,-50%); position: absolute; - left: -15px; + left: 10px; top: 50%; color: @red-l3; } @@ -153,7 +153,7 @@ .umb-help-list-item__content { display: flex; align-items: center; - padding: 10px 20px; + padding: 10px 20px 10px 10px; } .umb-help-list-item > a:hover, From 9488df823a48592dd44ccc156b1c961c478e9cee Mon Sep 17 00:00:00 2001 From: Nathan Woulfe Date: Wed, 18 Jul 2018 11:00:27 +1000 Subject: [PATCH 038/134] remove inline styles in help drawer --- .../components/application/umb-drawer.less | 35 +++++++++++++++---- .../src/views/common/drawers/help/help.html | 31 ++++++++-------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less b/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less index abcace794f..3c979135fb 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less @@ -61,6 +61,7 @@ overflow: hidden; border-radius: 3px; display: block; + margin-bottom:5px; } .umb-help-badge:hover, @@ -128,6 +129,14 @@ align-items: center; } +/* the outer container for each help type - tours, video etc */ +.umb-help-section + .umb-help-section { + margin-top:20px; +} + +.umb-help-section__title { + margin:0 0 10px; +} /* Help list */ @@ -135,12 +144,12 @@ list-style: none; margin-left: 0; margin-bottom: 0; - background: @white; + background: @white; border-radius: 3px; -} - -.umb-help-list:last-child { - border-bottom: none; + + [data-element*="help-tours"] & { + margin-bottom:5px; + } } .umb-help-list-item { @@ -149,20 +158,28 @@ border-bottom: 1px solid @gray-9; } -.umb-help-list-item > a, +.umb-help-list-item__group-title i { + margin-right:2px; + text-decoration: none; +} + .umb-help-list-item__content { display: flex; align-items: center; padding: 10px 20px 10px 10px; + text-decoration: none; } +.umb-help-list-item:hover, +.umb-help-list-item:focus, +.umb-help-list-item:active, .umb-help-list-item > a:hover, .umb-help-list-item > a:focus, .umb-help-list-item > a:active { text-decoration: none; .umb-help-list-item__title { - text-decoration: underline !important; + text-decoration: underline; } } @@ -191,4 +208,8 @@ .umb-help-list-item:hover .umb-help-list-item__group-title { text-decoration: underline; +} + +[data-element*="tour-"].umb-help-list-item:hover .umb-help-list-item__title { + text-decoration:none; } \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.html b/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.html index 4829c8964a..a4d4af6093 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.html @@ -8,16 +8,17 @@ -
+
-
Tours
+
Tours
-
+
- -
+ +
+ {{tourGroup.group}} Other
@@ -49,7 +50,7 @@ -
+
@@ -61,11 +62,11 @@
-
-
Articles
+
-
-
Videos
+
-
- +
+
Visit umbraco.tv
@@ -102,7 +103,7 @@
-
+
Visit our.umbraco.org
From 017b5353db544fc5e84d7f3e08ccb4e50f459eeb Mon Sep 17 00:00:00 2001 From: Nathan Woulfe Date: Wed, 18 Jul 2018 14:02:26 +1000 Subject: [PATCH 039/134] remove direct IO operation, replace with exisiting repository method --- src/Umbraco.Core/Services/FileService.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs index 4428175fa9..e7560e5636 100644 --- a/src/Umbraco.Core/Services/FileService.cs +++ b/src/Umbraco.Core/Services/FileService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; +using System.Text; using System.Text.RegularExpressions; using Umbraco.Core.Events; using Umbraco.Core.IO; @@ -1108,9 +1109,15 @@ namespace Umbraco.Core.Services return string.Empty; } - using (var view = new StreamReader(System.IO.File.OpenRead(viewAttempt.Result))) + using (var uow = UowProvider.GetUnitOfWork()) { - return view.ReadToEnd().Trim(); + var repository = RepositoryFactory.CreateTemplateRepository(uow); + var stream = repository.GetFileContentStream(viewAttempt.Result); + + using (var reader = new StreamReader(stream, Encoding.UTF8, true)) + { + return reader.ReadToEnd().Trim(); + } } } From fe648c8069e83f83f165f8498ea49f86312288b2 Mon Sep 17 00:00:00 2001 From: Nathan Woulfe Date: Wed, 18 Jul 2018 14:27:18 +1000 Subject: [PATCH 040/134] get view content in service methods rather than controller --- src/Umbraco.Core/Services/FileService.cs | 20 +++++++++++++++---- src/Umbraco.Core/Services/IFileService.cs | 7 ------- src/Umbraco.Web/Editors/TemplateController.cs | 9 --------- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs index e7560e5636..f81110c338 100644 --- a/src/Umbraco.Core/Services/FileService.cs +++ b/src/Umbraco.Core/Services/FileService.cs @@ -295,7 +295,7 @@ namespace Umbraco.Core.Services // check that the template hasn't been created on disk before creating the content type // if it exists, set the new template content to the existing file content string content = GetViewContent(contentTypeAlias); - if (content.IsNullOrWhiteSpace() == false) + if (content != null) { template.Content = content; } @@ -321,17 +321,29 @@ namespace Umbraco.Core.Services return Attempt.Succeed(new OperationStatus(template, OperationStatusType.Success, evtMsgs)); } + /// + /// Create a new template, setting the content if a view exists in the filesystem + /// + /// + /// + /// + /// + /// public ITemplate CreateTemplateWithIdentity(string name, string content, ITemplate masterTemplate = null, int userId = 0) { + // file might already be on disk, if so grab the content to avoid overwriting var template = new Template(name, name) { - Content = content + Content = GetViewContent(name) ?? content }; + if (masterTemplate != null) { template.SetMasterTemplate(masterTemplate); } + SaveTemplate(template, userId); + return template; } @@ -1098,7 +1110,7 @@ namespace Umbraco.Core.Services return GetPartialViewMacroSnippetContent(snippetName, PartialViewType.PartialViewMacro); } - public string GetViewContent(string filename) + private string GetViewContent(string filename) { if (filename.IsNullOrWhiteSpace()) throw new ArgumentNullException(nameof(filename)); @@ -1106,7 +1118,7 @@ namespace Umbraco.Core.Services Attempt viewAttempt = TryGetViewPath(filename); if (viewAttempt.Success == false) { - return string.Empty; + return null; } using (var uow = UowProvider.GetUnitOfWork()) diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs index 0031562697..b798b2c5ae 100644 --- a/src/Umbraco.Core/Services/IFileService.cs +++ b/src/Umbraco.Core/Services/IFileService.cs @@ -427,12 +427,5 @@ namespace Umbraco.Core.Services /// The filesystem path to the partial view. /// The size of the partial view. long GetPartialViewFileSize(string filepath); - - /// - /// Gets the content of a view. - /// - /// The name of the view. - /// - string GetViewContent(string filename); } } diff --git a/src/Umbraco.Web/Editors/TemplateController.cs b/src/Umbraco.Web/Editors/TemplateController.cs index 132e804a95..100a266dff 100644 --- a/src/Umbraco.Web/Editors/TemplateController.cs +++ b/src/Umbraco.Web/Editors/TemplateController.cs @@ -176,14 +176,6 @@ namespace Umbraco.Web.Editors else { //create - - // file might already be on disk, if so grab the content to avoid overwriting - string content = Services.FileService.GetViewContent(display.Alias); - if (string.IsNullOrEmpty(content) == false) - { - display.Content = content; - } - ITemplate master = null; if (string.IsNullOrEmpty(display.MasterTemplateAlias) == false) { @@ -193,7 +185,6 @@ namespace Umbraco.Web.Editors } var template = Services.FileService.CreateTemplateWithIdentity(display.Name, display.Content, master); - //template = Services.FileService.GetTemplate(template.Id); Mapper.Map(template, display); } From 7a9a4a2fab99e1946a8479e1b6b767cc0dfddc57 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 18 Jul 2018 10:54:19 +0100 Subject: [PATCH 041/134] Fixes bug with comparing partial content paths Raised here in a comment by @coolmikkel https://github.com/umbraco/Umbraco-CMS/pull/2253#issuecomment-405751083 --- src/Umbraco.Web/PublishedContentExtensions.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index a7dcdccdf0..f1dd008e38 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -860,7 +860,7 @@ namespace Umbraco.Web public static bool IsDescendant(this IPublishedContent content, IPublishedContent other) { - return other.Level < content.Level && content.Path.InvariantStartsWith(other.Path); + return other.Level < content.Level && content.Path.InvariantStartsWith(other.Path.EnsureEndsWith(',')); } public static HtmlString IsDescendant(this IPublishedContent content, IPublishedContent other, string valueIfTrue) @@ -875,7 +875,7 @@ namespace Umbraco.Web public static bool IsDescendantOrSelf(this IPublishedContent content, IPublishedContent other) { - return content.Path.InvariantStartsWith(other.Path); + return content.Path.InvariantEquals(other.Path) || content.IsDescendant(other); } public static HtmlString IsDescendantOrSelf(this IPublishedContent content, IPublishedContent other, string valueIfTrue) @@ -890,8 +890,7 @@ namespace Umbraco.Web public static bool IsAncestor(this IPublishedContent content, IPublishedContent other) { - // avoid using Descendants(), or Ancestors(), they're expensive - return content.Level < other.Level && other.Path.InvariantStartsWith(content.Path); + return content.Level < other.Level && other.Path.InvariantStartsWith(content.Path.EnsureEndsWith(',')); } public static HtmlString IsAncestor(this IPublishedContent content, IPublishedContent other, string valueIfTrue) @@ -906,8 +905,7 @@ namespace Umbraco.Web public static bool IsAncestorOrSelf(this IPublishedContent content, IPublishedContent other) { - // avoid using DescendantsOrSelf() or AncestorsOrSelf(), they're expensive - return other.Path.InvariantStartsWith(content.Path); + return other.Path.InvariantEquals(content.Path) || content.IsAncestor(other); } public static HtmlString IsAncestorOrSelf(this IPublishedContent content, IPublishedContent other, string valueIfTrue) From 2da5a522b0e7b51543a73a2adaddedc0d4bbd425 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 18 Jul 2018 10:56:31 +0100 Subject: [PATCH 042/134] Updated PublishedContent unit-test to support the fix in commit 7a9a4a2fab99e1946a8479e1b6b767cc0dfddc57 However this meant that I had to update a bunch of other unit-tests, due to hardcoded counts/references on the content XML. --- .../PublishedContent/PublishedContentTests.cs | 58 ++++++++++++++----- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs index abb22c2478..db7fcb815a 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs @@ -93,13 +93,14 @@ namespace Umbraco.Tests.PublishedContent - - - - - + + + + + + - 1 + 1 @@ -183,7 +184,7 @@ namespace Umbraco.Tests.PublishedContent .Where(x => x.IsVisible()) .ToContentSet(); - Assert.AreEqual(3, items.Count()); + Assert.AreEqual(4, items.Count()); foreach (var d in items) { @@ -193,6 +194,10 @@ namespace Umbraco.Tests.PublishedContent Assert.IsTrue(d.IsFirst()); Assert.IsFalse(d.IsLast()); break; + case 117: + Assert.IsFalse(d.IsFirst()); + Assert.IsFalse(d.IsLast()); + break; case 1177: Assert.IsFalse(d.IsFirst()); Assert.IsFalse(d.IsLast()); @@ -255,7 +260,7 @@ namespace Umbraco.Tests.PublishedContent { var doc = GetNode(1173); - var items = doc.Children.Take(3).ToContentSet(); + var items = doc.Children.Take(4).ToContentSet(); foreach (var item in items) { @@ -315,7 +320,7 @@ namespace Umbraco.Tests.PublishedContent { var doc = GetNode(1046); - var expected = new[] { 1046, 1173, 1174, 1177, 1178, 1179, 1176, 1175, 4444, 1172 }; + var expected = new[] { 1046, 1173, 1174, 117, 1177, 1178, 1179, 1176, 1175, 4444, 1172 }; var exindex = 0; // must respect the XPath descendants-or-self axis! @@ -370,11 +375,11 @@ namespace Umbraco.Tests.PublishedContent var doc = GetNode(1173); Assert.AreEqual(0, doc.Index()); doc = GetNode(1176); - Assert.AreEqual(3, doc.Index()); + Assert.AreEqual(4, doc.Index()); doc = GetNode(1177); - Assert.AreEqual(1, doc.Index()); - doc = GetNode(1178); Assert.AreEqual(2, doc.Index()); + doc = GetNode(1178); + Assert.AreEqual(3, doc.Index()); } [Test] @@ -600,6 +605,7 @@ namespace Umbraco.Tests.PublishedContent // -- Home: 1173 (parent 1046) // -- Custom Doc: 1178 (parent 1173) // --- Custom Doc2: 1179 (parent: 1178) + // -- Custom Doc4: 117 (parent 1173) // - Custom Doc3: 1172 (no parent) var home = GetNode(1173); @@ -607,25 +613,30 @@ namespace Umbraco.Tests.PublishedContent var customDoc = GetNode(1178); var customDoc2 = GetNode(1179); var customDoc3 = GetNode(1172); + var customDoc4 = GetNode(117); + Assert.IsTrue(root.IsAncestor(customDoc4)); Assert.IsFalse(root.IsAncestor(customDoc3)); Assert.IsTrue(root.IsAncestor(customDoc2)); Assert.IsTrue(root.IsAncestor(customDoc)); Assert.IsTrue(root.IsAncestor(home)); Assert.IsFalse(root.IsAncestor(root)); + Assert.IsTrue(home.IsAncestor(customDoc4)); Assert.IsFalse(home.IsAncestor(customDoc3)); Assert.IsTrue(home.IsAncestor(customDoc2)); Assert.IsTrue(home.IsAncestor(customDoc)); Assert.IsFalse(home.IsAncestor(home)); Assert.IsFalse(home.IsAncestor(root)); + Assert.IsFalse(customDoc.IsAncestor(customDoc4)); Assert.IsFalse(customDoc.IsAncestor(customDoc3)); Assert.IsTrue(customDoc.IsAncestor(customDoc2)); Assert.IsFalse(customDoc.IsAncestor(customDoc)); Assert.IsFalse(customDoc.IsAncestor(home)); Assert.IsFalse(customDoc.IsAncestor(root)); + Assert.IsFalse(customDoc2.IsAncestor(customDoc4)); Assert.IsFalse(customDoc2.IsAncestor(customDoc3)); Assert.IsFalse(customDoc2.IsAncestor(customDoc2)); Assert.IsFalse(customDoc2.IsAncestor(customDoc)); @@ -643,6 +654,7 @@ namespace Umbraco.Tests.PublishedContent // -- Home: 1173 (parent 1046) // -- Custom Doc: 1178 (parent 1173) // --- Custom Doc2: 1179 (parent: 1178) + // -- Custom Doc4: 117 (parent 1173) // - Custom Doc3: 1172 (no parent) var home = GetNode(1173); @@ -650,31 +662,37 @@ namespace Umbraco.Tests.PublishedContent var customDoc = GetNode(1178); var customDoc2 = GetNode(1179); var customDoc3 = GetNode(1172); + var customDoc4 = GetNode(117); + Assert.IsTrue(root.IsAncestorOrSelf(customDoc4)); Assert.IsFalse(root.IsAncestorOrSelf(customDoc3)); Assert.IsTrue(root.IsAncestorOrSelf(customDoc2)); Assert.IsTrue(root.IsAncestorOrSelf(customDoc)); Assert.IsTrue(root.IsAncestorOrSelf(home)); Assert.IsTrue(root.IsAncestorOrSelf(root)); + Assert.IsTrue(home.IsAncestorOrSelf(customDoc4)); Assert.IsFalse(home.IsAncestorOrSelf(customDoc3)); Assert.IsTrue(home.IsAncestorOrSelf(customDoc2)); Assert.IsTrue(home.IsAncestorOrSelf(customDoc)); Assert.IsTrue(home.IsAncestorOrSelf(home)); Assert.IsFalse(home.IsAncestorOrSelf(root)); + Assert.IsFalse(customDoc.IsAncestorOrSelf(customDoc4)); Assert.IsFalse(customDoc.IsAncestorOrSelf(customDoc3)); Assert.IsTrue(customDoc.IsAncestorOrSelf(customDoc2)); Assert.IsTrue(customDoc.IsAncestorOrSelf(customDoc)); Assert.IsFalse(customDoc.IsAncestorOrSelf(home)); Assert.IsFalse(customDoc.IsAncestorOrSelf(root)); + Assert.IsFalse(customDoc2.IsAncestorOrSelf(customDoc4)); Assert.IsFalse(customDoc2.IsAncestorOrSelf(customDoc3)); Assert.IsTrue(customDoc2.IsAncestorOrSelf(customDoc2)); Assert.IsFalse(customDoc2.IsAncestorOrSelf(customDoc)); Assert.IsFalse(customDoc2.IsAncestorOrSelf(home)); Assert.IsFalse(customDoc2.IsAncestorOrSelf(root)); + Assert.IsTrue(customDoc4.IsAncestorOrSelf(customDoc4)); Assert.IsTrue(customDoc3.IsAncestorOrSelf(customDoc3)); } @@ -688,7 +706,7 @@ namespace Umbraco.Tests.PublishedContent Assert.IsNotNull(result); - Assert.AreEqual(9, result.Count()); + Assert.AreEqual(10, result.Count()); Assert.IsTrue(result.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1046, 1173, 1174, 1176, 1175 })); } @@ -701,7 +719,7 @@ namespace Umbraco.Tests.PublishedContent Assert.IsNotNull(result); - Assert.AreEqual(8, result.Count()); + Assert.AreEqual(9, result.Count()); Assert.IsTrue(result.Select(x => ((dynamic)x).Id).ContainsAll(new dynamic[] { 1173, 1174, 1176, 1175, 4444 })); } @@ -713,6 +731,7 @@ namespace Umbraco.Tests.PublishedContent // -- Home: 1173 (parent 1046) // -- Custom Doc: 1178 (parent 1173) // --- Custom Doc2: 1179 (parent: 1178) + // -- Custom Doc4: 117 (parent 1173) // - Custom Doc3: 1172 (no parent) var home = GetNode(1173); @@ -720,30 +739,35 @@ namespace Umbraco.Tests.PublishedContent var customDoc = GetNode(1178); var customDoc2 = GetNode(1179); var customDoc3 = GetNode(1172); + var customDoc4 = GetNode(117); Assert.IsFalse(root.IsDescendant(root)); Assert.IsFalse(root.IsDescendant(home)); Assert.IsFalse(root.IsDescendant(customDoc)); Assert.IsFalse(root.IsDescendant(customDoc2)); Assert.IsFalse(root.IsDescendant(customDoc3)); + Assert.IsFalse(root.IsDescendant(customDoc4)); Assert.IsTrue(home.IsDescendant(root)); Assert.IsFalse(home.IsDescendant(home)); Assert.IsFalse(home.IsDescendant(customDoc)); Assert.IsFalse(home.IsDescendant(customDoc2)); Assert.IsFalse(home.IsDescendant(customDoc3)); + Assert.IsFalse(home.IsDescendant(customDoc4)); Assert.IsTrue(customDoc.IsDescendant(root)); Assert.IsTrue(customDoc.IsDescendant(home)); Assert.IsFalse(customDoc.IsDescendant(customDoc)); Assert.IsFalse(customDoc.IsDescendant(customDoc2)); Assert.IsFalse(customDoc.IsDescendant(customDoc3)); + Assert.IsFalse(customDoc.IsDescendant(customDoc4)); Assert.IsTrue(customDoc2.IsDescendant(root)); Assert.IsTrue(customDoc2.IsDescendant(home)); Assert.IsTrue(customDoc2.IsDescendant(customDoc)); Assert.IsFalse(customDoc2.IsDescendant(customDoc2)); Assert.IsFalse(customDoc2.IsDescendant(customDoc3)); + Assert.IsFalse(customDoc2.IsDescendant(customDoc4)); Assert.IsFalse(customDoc3.IsDescendant(customDoc3)); } @@ -756,6 +780,7 @@ namespace Umbraco.Tests.PublishedContent // -- Home: 1173 (parent 1046) // -- Custom Doc: 1178 (parent 1173) // --- Custom Doc2: 1179 (parent: 1178) + // -- Custom Doc4: 117 (parent 1173) // - Custom Doc3: 1172 (no parent) var home = GetNode(1173); @@ -763,30 +788,35 @@ namespace Umbraco.Tests.PublishedContent var customDoc = GetNode(1178); var customDoc2 = GetNode(1179); var customDoc3 = GetNode(1172); + var customDoc4 = GetNode(117); Assert.IsTrue(root.IsDescendantOrSelf(root)); Assert.IsFalse(root.IsDescendantOrSelf(home)); Assert.IsFalse(root.IsDescendantOrSelf(customDoc)); Assert.IsFalse(root.IsDescendantOrSelf(customDoc2)); Assert.IsFalse(root.IsDescendantOrSelf(customDoc3)); + Assert.IsFalse(root.IsDescendantOrSelf(customDoc4)); Assert.IsTrue(home.IsDescendantOrSelf(root)); Assert.IsTrue(home.IsDescendantOrSelf(home)); Assert.IsFalse(home.IsDescendantOrSelf(customDoc)); Assert.IsFalse(home.IsDescendantOrSelf(customDoc2)); Assert.IsFalse(home.IsDescendantOrSelf(customDoc3)); + Assert.IsFalse(home.IsDescendantOrSelf(customDoc4)); Assert.IsTrue(customDoc.IsDescendantOrSelf(root)); Assert.IsTrue(customDoc.IsDescendantOrSelf(home)); Assert.IsTrue(customDoc.IsDescendantOrSelf(customDoc)); Assert.IsFalse(customDoc.IsDescendantOrSelf(customDoc2)); Assert.IsFalse(customDoc.IsDescendantOrSelf(customDoc3)); + Assert.IsFalse(customDoc.IsDescendantOrSelf(customDoc4)); Assert.IsTrue(customDoc2.IsDescendantOrSelf(root)); Assert.IsTrue(customDoc2.IsDescendantOrSelf(home)); Assert.IsTrue(customDoc2.IsDescendantOrSelf(customDoc)); Assert.IsTrue(customDoc2.IsDescendantOrSelf(customDoc2)); Assert.IsFalse(customDoc2.IsDescendantOrSelf(customDoc3)); + Assert.IsFalse(customDoc2.IsDescendantOrSelf(customDoc4)); Assert.IsTrue(customDoc3.IsDescendantOrSelf(customDoc3)); } From 06f014df617d9c8d8055459c6e0c95c52bab6deb Mon Sep 17 00:00:00 2001 From: Nathan Woulfe Date: Thu, 19 Jul 2018 08:28:07 +1000 Subject: [PATCH 043/134] remove TryGetViewPath as not needed --- src/Umbraco.Core/Services/FileService.cs | 25 ++++++++---------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs index f81110c338..fc1bbf34d2 100644 --- a/src/Umbraco.Core/Services/FileService.cs +++ b/src/Umbraco.Core/Services/FileService.cs @@ -1066,19 +1066,6 @@ namespace Umbraco.Core.Services : Attempt.Fail(); } - internal Attempt TryGetViewPath(string fileName) - { - if (fileName.EndsWith(".cshtml") == false) - { - fileName += ".cshtml"; - } - - string viewPath = IOHelper.MapPath(SystemDirectories.MvcViews + "/" + fileName); - return System.IO.File.Exists(viewPath) - ? Attempt.Succeed(viewPath) - : Attempt.Fail(); - } - private IPartialViewRepository GetPartialViewRepository(PartialViewType partialViewType, IUnitOfWork uow) { switch (partialViewType) @@ -1115,16 +1102,20 @@ namespace Umbraco.Core.Services if (filename.IsNullOrWhiteSpace()) throw new ArgumentNullException(nameof(filename)); - Attempt viewAttempt = TryGetViewPath(filename); - if (viewAttempt.Success == false) + if (filename.EndsWith(".cshtml") == false) { - return null; + filename = $"{filename}.cshtml"; } using (var uow = UowProvider.GetUnitOfWork()) { var repository = RepositoryFactory.CreateTemplateRepository(uow); - var stream = repository.GetFileContentStream(viewAttempt.Result); + var stream = repository.GetFileContentStream(filename); + + if (stream == null) + { + return null; + } using (var reader = new StreamReader(stream, Encoding.UTF8, true)) { From 88b6f4e436be4258629b261bbb64f4fbf9e28627 Mon Sep 17 00:00:00 2001 From: Gareth Evans Date: Fri, 20 Jul 2018 11:42:52 +1200 Subject: [PATCH 044/134] Guard gridController.addRow from setting form state to dirty if invoked from initSection --- .../src/views/propertyeditors/grid/grid.controller.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index b59fc6ecad..4bb412de5d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js @@ -333,7 +333,7 @@ angular.module("umbraco") } } - $scope.addRow = function (section, layout) { + $scope.addRow = function (section, layout, isInit) { //copy the selected layout into the rows collection var row = angular.copy(layout); @@ -345,8 +345,9 @@ angular.module("umbraco") if (row) { section.rows.push(row); } - - currentForm.$setDirty(); + if (!isInit) { + currentForm.$setDirty(); + } $scope.showRowConfigurations = false; @@ -728,7 +729,7 @@ angular.module("umbraco") if (!section.rows || section.rows.length === 0) { section.rows = []; if(section.$allowedLayouts.length === 1){ - $scope.addRow(section, section.$allowedLayouts[0]); + $scope.addRow(section, section.$allowedLayouts[0], true); } } else { _.forEach(section.rows, function (row, index) { From e0b15070569d58d4c6532c90e0c26d6fb0b5fe1a Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 23 Jul 2018 23:22:52 +0200 Subject: [PATCH 045/134] Show/hide label field when label is toggled Adds dib class to parent div to make the click target smaller --- .../directives/components/buttons/umbtoggle.directive.js | 6 ++++-- .../src/views/components/buttons/umb-toggle.html | 4 ++-- .../propertyeditors/colorpicker/colorpicker.prevalues.html | 2 +- .../colorpicker/multicolorpicker.controller.js | 7 ++++++- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbtoggle.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbtoggle.directive.js index a7bdd4b741..e3c4cbf40c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbtoggle.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbtoggle.directive.js @@ -64,7 +64,7 @@ (function () { 'use strict'; - function ToggleDirective(localizationService) { + function ToggleDirective(localizationService, eventsService) { function link(scope, el, attr, ctrl) { @@ -73,6 +73,7 @@ function onInit() { setLabelText(); + eventsService.emit("toggleValue", { value: scope.checked }); } function setLabelText() { @@ -98,7 +99,8 @@ } scope.click = function() { - if(scope.onClick) { + if (scope.onClick) { + eventsService.emit("toggleValue", { value: !scope.checked }); scope.onClick(); } }; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-toggle.html b/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-toggle.html index c7c34b2eaa..e850bf22b8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-toggle.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-toggle.html @@ -1,4 +1,4 @@ -
+ {{ displayLabelOff }} @@ -16,4 +16,4 @@ {{ displayLabelOn }} - \ No newline at end of file + diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html index 2d342c92fc..1df2e87685 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html @@ -2,7 +2,7 @@
- +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js index f19fb260f4..3819b054a3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js @@ -1,5 +1,5 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.MultiColorPickerController", - function ($scope, $timeout, assetsService, angularHelper, $element, localizationService) { + function ($scope, $timeout, assetsService, angularHelper, $element, localizationService, eventsService) { //NOTE: We need to make each color an object, not just a string because you cannot 2-way bind to a primitive. var defaultColor = "000000"; var defaultLabel = null; @@ -15,6 +15,11 @@ "general_choose" ]; + $scope.labelEnabled = false; + eventsService.on("toggleValue", function (e, args) { + $scope.labelEnabled = args.value; + }); + localizationService.localizeMany(labelKeys).then(function (values) { $scope.labels.cancel = values[0]; $scope.labels.choose = values[1]; From 43fd34ab800ead6e402db49482cfa2e08e9a37e1 Mon Sep 17 00:00:00 2001 From: agrath Date: Wed, 25 Jul 2018 02:10:30 +1200 Subject: [PATCH 046/134] =?UTF-8?q?U4-11152=20Add=20visual=20indicator=20t?= =?UTF-8?q?o=20trashed=20media=20items=20in=20the=20media=20pic=E2=80=A6?= =?UTF-8?q?=20(#2542)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Umbraco.Web.UI.Client/src/less/property-editors.less | 9 +++++++++ .../views/propertyeditors/mediapicker/mediapicker.html | 1 + src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 1 + src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 1 + src/Umbraco.Web.UI/umbraco/config/lang/ru.xml | 9 --------- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index dd0e4d3e77..c96a965616 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -242,6 +242,15 @@ ul.color-picker li a { text-decoration: none; } +.umb-mediapicker .label.trashed { + position: absolute; + top: 5px; + right: 5px; + color: #fff; + background-color: #fe6561; + background-image: linear-gradient(180deg,#fe6561,#fe6561); +} + .umb-mediapicker .add-link-square { height: 120px; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html index 7607a9391d..fd28929616 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.html @@ -7,6 +7,7 @@
diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs index 1e59aa1c93..28f7e898cf 100644 --- a/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs +++ b/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs @@ -28,6 +28,15 @@ namespace Umbraco.Web.Models.ContentEditing [DataMember(Name = "template")] public string TemplateAlias { get; set; } + + + + [DataMember(Name = "templateId")] + public int TemplateId { get; set; } + + + + [DataMember(Name = "allowedTemplates")] public IDictionary AllowedTemplates { get; set; } @@ -58,4 +67,4 @@ namespace Umbraco.Web.Models.ContentEditing [DataMember(Name = "isBlueprint")] public bool IsBlueprint { get; set; } } -} \ No newline at end of file +} From c264368042fd5644286466fc74dfc199fda7b3ad Mon Sep 17 00:00:00 2001 From: skidmow Date: Wed, 25 Jul 2018 09:06:29 +0100 Subject: [PATCH 049/134] U4-11528 Problem with length of culture in database (#2791) --- src/Umbraco.Core/Models/Rdbms/LanguageDto.cs | 4 +-- .../IncreaseLanguageIsoCodeColumnLength.cs | 26 +++++++++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/IncreaseLanguageIsoCodeColumnLength.cs diff --git a/src/Umbraco.Core/Models/Rdbms/LanguageDto.cs b/src/Umbraco.Core/Models/Rdbms/LanguageDto.cs index a634dca0a4..cad023119a 100644 --- a/src/Umbraco.Core/Models/Rdbms/LanguageDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/LanguageDto.cs @@ -15,7 +15,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("languageISOCode")] [Index(IndexTypes.UniqueNonClustered)] [NullSetting(NullSetting = NullSettings.Null)] - [Length(10)] + [Length(14)] public string IsoCode { get; set; } [Column("languageCultureName")] @@ -23,4 +23,4 @@ namespace Umbraco.Core.Models.Rdbms [Length(100)] public string CultureName { get; set; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/IncreaseLanguageIsoCodeColumnLength.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/IncreaseLanguageIsoCodeColumnLength.cs new file mode 100644 index 0000000000..8f61c09af3 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/IncreaseLanguageIsoCodeColumnLength.cs @@ -0,0 +1,26 @@ +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwelveZero +{ + [Migration("7.12.0", 2, Constants.System.UmbracoMigrationName)] + public class IncreaseLanguageIsoCodeColumnLength : MigrationBase + { + public IncreaseLanguageIsoCodeColumnLength(ISqlSyntaxProvider sqlSyntax, ILogger logger) + : base(sqlSyntax, logger) + { + } + + public override void Up() + { + Alter.Table("umbracoLanguage") + .AlterColumn("languageISOCode") + .AsString(14) + .Nullable(); + } + + public override void Down() + { + } + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 337fad89dc..cc4c94a3bc 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -636,6 +636,7 @@ + From 4e1e9e0687b6babb56871cd81a34764e0d9a509e Mon Sep 17 00:00:00 2001 From: Jan Skovgaard Date: Sun, 15 Jul 2018 13:10:59 +0200 Subject: [PATCH 050/134] Switch JSON to be the default storage option and changing the storage type text to say JSON is default and CSV is legacy --- src/Umbraco.Core/Models/TagCacheStorageType.cs | 6 +++--- src/Umbraco.Core/PropertyEditors/SupportTagsAttribute.cs | 4 ++-- .../src/views/propertyeditors/tags/tags.prevalues.html | 4 ++-- src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Core/Models/TagCacheStorageType.cs b/src/Umbraco.Core/Models/TagCacheStorageType.cs index 5078a44d85..5b7be84fb8 100644 --- a/src/Umbraco.Core/Models/TagCacheStorageType.cs +++ b/src/Umbraco.Core/Models/TagCacheStorageType.cs @@ -2,7 +2,7 @@ { public enum TagCacheStorageType { - Csv, - Json + Json, + Csv } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/PropertyEditors/SupportTagsAttribute.cs b/src/Umbraco.Core/PropertyEditors/SupportTagsAttribute.cs index 3ff124d345..c0238e16e8 100644 --- a/src/Umbraco.Core/PropertyEditors/SupportTagsAttribute.cs +++ b/src/Umbraco.Core/PropertyEditors/SupportTagsAttribute.cs @@ -31,7 +31,7 @@ namespace Umbraco.Core.PropertyEditors Delimiter = ","; ReplaceTags = true; TagGroup = "default"; - StorageType = TagCacheStorageType.Csv; + StorageType = TagCacheStorageType.Json; } /// @@ -59,4 +59,4 @@ namespace Umbraco.Core.PropertyEditors /// public string TagGroup { get; set; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.prevalues.html index 2eb9aecf1e..d1113c41a4 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.prevalues.html @@ -3,8 +3,8 @@ -
\ No newline at end of file +
diff --git a/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs index 1faa6ed0ab..a843384fe4 100644 --- a/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs @@ -19,7 +19,7 @@ namespace Umbraco.Web.PropertyEditors _defaultPreVals = new Dictionary { {"group", "default"}, - {"storageType", TagCacheStorageType.Csv.ToString()} + {"storageType", TagCacheStorageType.Json.ToString()} }; } @@ -133,7 +133,7 @@ namespace Umbraco.Web.PropertyEditors Fields.Add(new PreValueField(new ManifestPropertyValidator {Type = "Required"}) { - Description = "Select whether to store the tags in cache as CSV (default) or as JSON. The only benefits of storage as JSON is that you are able to have commas in a tag value", + Description = "Select whether to store the tags in cache as JSON (default) or as CSV (Legacy).", Key = "storageType", Name = "Storage Type", View = "views/propertyeditors/tags/tags.prevalues.html" From 9180ab4442a25925192da08a7ea5d42ebe7e7af7 Mon Sep 17 00:00:00 2001 From: Jan Skovgaard Date: Tue, 17 Jul 2018 17:07:54 +0200 Subject: [PATCH 051/134] Reset commit to not break backwards compatibility mode --- src/Umbraco.Core/Models/TagCacheStorageType.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/Models/TagCacheStorageType.cs b/src/Umbraco.Core/Models/TagCacheStorageType.cs index 5b7be84fb8..5078a44d85 100644 --- a/src/Umbraco.Core/Models/TagCacheStorageType.cs +++ b/src/Umbraco.Core/Models/TagCacheStorageType.cs @@ -2,7 +2,7 @@ { public enum TagCacheStorageType { - Json, - Csv + Csv, + Json } -} +} \ No newline at end of file From 92f0d0d2eacd83095e838f39b54bb0ec2cb1c962 Mon Sep 17 00:00:00 2001 From: Jan Skovgaard Date: Wed, 25 Jul 2018 09:34:03 +0200 Subject: [PATCH 052/134] Add a new migration to set the default storageType for Umbraco.Tags datatype to CSV if it has not been set previously --- .../SetDefaultTagsStorageType.cs | 48 +++++++++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + 2 files changed, 49 insertions(+) create mode 100644 src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs new file mode 100644 index 0000000000..9e4fe95100 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs @@ -0,0 +1,48 @@ +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenElevenTwelve +{ + /// + /// Set the default storageType for the tags datatype to "CSV" to ensure backwards compatibilty since the default is going to be JSON in new versions + /// + + [Migration("7.12.0", 1, Constants.System.UmbracoMigrationName)] + public class SetDefaultTagsStorageType: MigrationBase + { + public SetDefaultTagsStorageType(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger) + { + } + + public override void Up() + { + if (Context == null || Context.Database == null) return; + + + // We need to get all datatypes with an alias of "umbraco.tags" so we can loop over them and set the missing values if needed + var nodeIds = Context.Database.Query("SELECT NodeId FROM CmsDataType WHERE PropertyEditorAlias = {0}", Constants.PropertyEditors.TagsAlias); + + foreach (var nodeId in nodeIds) + { + // We need to check if the node has a "storageType" set + var result = Context.Database.SingleOrDefault("SELECT value FROM CmsDataTypePrevalue WHERE nodeId = {0} AND alias = '{1}'", nodeId, "storageType"); + + // if the "storageType" has not been set we do so by adding a new row in the table for the nodid and set it + if (result == null) + { + Insert.IntoTable("CmsDataTypePrevalue").Row(new + { + datatypeNodId = nodeId, + value = "Csv", + sortOrder = 2, + alias = "storageType" + }); + } + } + } + + public override void Down() + { + } + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index cc4c94a3bc..1de2b1db89 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -568,6 +568,7 @@ + From 808fc14b32ebef317a9a814bcdeec167857e090b Mon Sep 17 00:00:00 2001 From: Jan Skovgaard Date: Wed, 25 Jul 2018 09:34:47 +0200 Subject: [PATCH 053/134] Set the default storageType for the Umbraco.Tags datatype to "Json", which is now going to be the default --- .../Migrations/Initial/BaseDataCreation.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs index 45dbeb72bc..f6724f205b 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs @@ -190,18 +190,18 @@ namespace Umbraco.Core.Persistence.Migrations.Initial private void CreateUmbracoUserGroup2AppData() { _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Content }); - _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Developer }); + _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Developer }); _database.Insert(new UserGroup2AppDto { UserGroupId = 1, AppAlias = Constants.Applications.Media }); _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 = 2, AppAlias = Constants.Applications.Content }); + _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.Forms }); + _database.Insert(new UserGroup2AppDto { UserGroupId = 3, AppAlias = Constants.Applications.Forms }); _database.Insert(new UserGroup2AppDto { UserGroupId = 4, AppAlias = Constants.Applications.Translation }); } @@ -289,6 +289,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial { _database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = 3, Alias = "", SortOrder = 0, DataTypeNodeId = -87, Value = ",code,undo,redo,cut,copy,mcepasteword,stylepicker,bold,italic,bullist,numlist,outdent,indent,mcelink,unlink,mceinsertanchor,mceimage,umbracomacro,mceinserttable,umbracoembed,mcecharmap,|1|1,2,3,|0|500,400|1049,|true|" }); _database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = 4, Alias = "group", SortOrder = 0, DataTypeNodeId = 1041, Value = "default" }); + _database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = 5, Alias = "storageType", SortOrder = 0, DataTypeNodeId = 1041, Value = "Json" }); //defaults for the member list _database.Insert("cmsDataTypePreValues", "id", false, new DataTypePreValueDto { Id = -1, Alias = "pageSize", SortOrder = 1, DataTypeNodeId = Constants.System.DefaultMembersListViewDataTypeId, Value = "10" }); From 9a4c022ea37fa8a58eacbb3c181465d3c6cd8202 Mon Sep 17 00:00:00 2001 From: Jan Skovgaard Date: Wed, 25 Jul 2018 09:35:51 +0200 Subject: [PATCH 054/134] Remove stuff that has been commented out --- .../Persistence/Migrations/Initial/BaseDataCreation.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs index f6724f205b..e5a1afb07a 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs @@ -146,11 +146,6 @@ namespace Umbraco.Core.Persistence.Migrations.Initial _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1048, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1048", SortOrder = 2, UniqueId = new Guid("135D60E0-64D9-49ED-AB08-893C9BA44AE5"), Text = "Media Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1049, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1049", SortOrder = 2, UniqueId = new Guid("9DBBCBBB-2327-434A-B355-AF1B84E5010A"), Text = "Multiple Media Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1050, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1050", SortOrder = 2, UniqueId = new Guid("B4E3535A-1753-47E2-8568-602CF8CFEE6F"), Text = "Related Links", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - - //TODO: We're not creating these for 7.0 - //_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1039, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1039", SortOrder = 2, UniqueId = new Guid("06f349a9-c949-4b6a-8660-59c10451af42"), Text = "Ultimate Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - //_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1038, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1038", SortOrder = 2, UniqueId = new Guid("1251c96c-185c-4e9b-93f4-b48205573cbd"), Text = "Simple Editor", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - //_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1042, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1042", SortOrder = 2, UniqueId = new Guid("0a452bd5-83f9-4bc3-8403-1286e13fb77e"), Text = "Macro Container", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); } private void CreateUmbracoLockData() @@ -278,11 +273,6 @@ namespace Umbraco.Core.Persistence.Migrations.Initial _database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 28, DataTypeId = 1048, PropertyEditorAlias = Constants.PropertyEditors.MediaPicker2Alias, DbType = "Ntext" }); _database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 29, DataTypeId = 1049, PropertyEditorAlias = Constants.PropertyEditors.MediaPicker2Alias, DbType = "Ntext" }); _database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 30, DataTypeId = 1050, PropertyEditorAlias = Constants.PropertyEditors.RelatedLinks2Alias, DbType = "Ntext" }); - - //TODO: We're not creating these for 7.0 - //_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 19, DataTypeId = 1038, PropertyEditorAlias = Constants.PropertyEditors.MarkdownEditorAlias, DbType = "Ntext" }); - //_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 20, DataTypeId = 1039, PropertyEditorAlias = Constants.PropertyEditors.UltimatePickerAlias, DbType = "Ntext" }); - //_database.Insert("cmsDataType", "pk", false, new DataTypeDto { PrimaryKey = 23, DataTypeId = 1042, PropertyEditorAlias = Constants.PropertyEditors.MacroContainerAlias, DbType = "Ntext" }); } private void CreateCmsDataTypePreValuesData() From 2d7918843303689b6c9c2164be34a53bd5c019ac Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 25 Jul 2018 11:08:10 +0200 Subject: [PATCH 055/134] Correct some mistakes I made in queries --- .../SetDefaultTagsStorageType.cs | 26 ++++++++++++------- src/Umbraco.Core/Umbraco.Core.csproj | 2 +- 2 files changed, 17 insertions(+), 11 deletions(-) rename src/Umbraco.Core/Persistence/Migrations/Upgrades/{TargetVersionSevenElevenTwelve => TargetVersionSevenTwelveZero}/SetDefaultTagsStorageType.cs (56%) diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/SetDefaultTagsStorageType.cs similarity index 56% rename from src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs rename to src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/SetDefaultTagsStorageType.cs index 9e4fe95100..8e13fa1013 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/SetDefaultTagsStorageType.cs @@ -1,7 +1,10 @@ -using Umbraco.Core.Logging; +using System; +using System.Linq; +using Umbraco.Core.Logging; +using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.SqlSyntax; -namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenElevenTwelve +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwelveZero { /// /// Set the default storageType for the tags datatype to "CSV" to ensure backwards compatibilty since the default is going to be JSON in new versions @@ -16,23 +19,26 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenElevenT public override void Up() { - if (Context == null || Context.Database == null) return; - - + if (Context?.Database == null) return; + // We need to get all datatypes with an alias of "umbraco.tags" so we can loop over them and set the missing values if needed - var nodeIds = Context.Database.Query("SELECT NodeId FROM CmsDataType WHERE PropertyEditorAlias = {0}", Constants.PropertyEditors.TagsAlias); + var datatypes = Context.Database.Fetch("SELECT * FROM cmsDataType"); + var tagsDataTypes = datatypes.Where(x => string.Equals(x.PropertyEditorAlias, Constants.PropertyEditors.TagsAlias, StringComparison.InvariantCultureIgnoreCase)); + var dataTypePreValues = Context.Database.Fetch("SELECT * FROM cmsDataTypePrevalues"); - foreach (var nodeId in nodeIds) + foreach (var datatype in tagsDataTypes) { // We need to check if the node has a "storageType" set - var result = Context.Database.SingleOrDefault("SELECT value FROM CmsDataTypePrevalue WHERE nodeId = {0} AND alias = '{1}'", nodeId, "storageType"); + var result = dataTypePreValues.FirstOrDefault(x => + x.DataTypeNodeId == datatype.DataTypeId + && string.Equals(x.Alias, "storageType", StringComparison.InvariantCultureIgnoreCase)); // if the "storageType" has not been set we do so by adding a new row in the table for the nodid and set it if (result == null) { - Insert.IntoTable("CmsDataTypePrevalue").Row(new + Insert.IntoTable("CmsDataTypePrevalues").Row(new { - datatypeNodId = nodeId, + datatypeNodeId = datatype.DataTypeId, value = "Csv", sortOrder = 2, alias = "storageType" diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 1de2b1db89..9e6f0cb7e5 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -568,7 +568,7 @@ - + From 882fa42e2df7830b93ce04cdaa569ba940aeee05 Mon Sep 17 00:00:00 2001 From: BatJan Date: Wed, 25 Jul 2018 11:10:35 +0200 Subject: [PATCH 056/134] U4-11497 - Make JSON storage default on the Tags property editor (#2773) --- .../SetDefaultTagsStorageType.cs | 48 +++++++++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + 2 files changed, 49 insertions(+) create mode 100644 src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs new file mode 100644 index 0000000000..9e4fe95100 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs @@ -0,0 +1,48 @@ +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenElevenTwelve +{ + /// + /// Set the default storageType for the tags datatype to "CSV" to ensure backwards compatibilty since the default is going to be JSON in new versions + /// + + [Migration("7.12.0", 1, Constants.System.UmbracoMigrationName)] + public class SetDefaultTagsStorageType: MigrationBase + { + public SetDefaultTagsStorageType(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger) + { + } + + public override void Up() + { + if (Context == null || Context.Database == null) return; + + + // We need to get all datatypes with an alias of "umbraco.tags" so we can loop over them and set the missing values if needed + var nodeIds = Context.Database.Query("SELECT NodeId FROM CmsDataType WHERE PropertyEditorAlias = {0}", Constants.PropertyEditors.TagsAlias); + + foreach (var nodeId in nodeIds) + { + // We need to check if the node has a "storageType" set + var result = Context.Database.SingleOrDefault("SELECT value FROM CmsDataTypePrevalue WHERE nodeId = {0} AND alias = '{1}'", nodeId, "storageType"); + + // if the "storageType" has not been set we do so by adding a new row in the table for the nodid and set it + if (result == null) + { + Insert.IntoTable("CmsDataTypePrevalue").Row(new + { + datatypeNodId = nodeId, + value = "Csv", + sortOrder = 2, + alias = "storageType" + }); + } + } + } + + public override void Down() + { + } + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 9e6f0cb7e5..0fbfaa0b27 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -568,6 +568,7 @@ + From b744962066096fdd181e5e7c99a9575f0df7d314 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 25 Jul 2018 11:13:27 +0200 Subject: [PATCH 057/134] =?UTF-8?q?Cleaning=20up=20the=20mess=20I=20made?= =?UTF-8?q?=20=F0=9F=99=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SetDefaultTagsStorageType.cs | 48 ------------------- src/Umbraco.Core/Umbraco.Core.csproj | 1 - 2 files changed, 49 deletions(-) delete mode 100644 src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs deleted file mode 100644 index 9e4fe95100..0000000000 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenElevenTwelve/SetDefaultTagsStorageType.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Umbraco.Core.Logging; -using Umbraco.Core.Persistence.SqlSyntax; - -namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenElevenTwelve -{ - /// - /// Set the default storageType for the tags datatype to "CSV" to ensure backwards compatibilty since the default is going to be JSON in new versions - /// - - [Migration("7.12.0", 1, Constants.System.UmbracoMigrationName)] - public class SetDefaultTagsStorageType: MigrationBase - { - public SetDefaultTagsStorageType(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger) - { - } - - public override void Up() - { - if (Context == null || Context.Database == null) return; - - - // We need to get all datatypes with an alias of "umbraco.tags" so we can loop over them and set the missing values if needed - var nodeIds = Context.Database.Query("SELECT NodeId FROM CmsDataType WHERE PropertyEditorAlias = {0}", Constants.PropertyEditors.TagsAlias); - - foreach (var nodeId in nodeIds) - { - // We need to check if the node has a "storageType" set - var result = Context.Database.SingleOrDefault("SELECT value FROM CmsDataTypePrevalue WHERE nodeId = {0} AND alias = '{1}'", nodeId, "storageType"); - - // if the "storageType" has not been set we do so by adding a new row in the table for the nodid and set it - if (result == null) - { - Insert.IntoTable("CmsDataTypePrevalue").Row(new - { - datatypeNodId = nodeId, - value = "Csv", - sortOrder = 2, - alias = "storageType" - }); - } - } - } - - public override void Down() - { - } - } -} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 0fbfaa0b27..9e6f0cb7e5 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -568,7 +568,6 @@ - From 4442afc1fddb93720bd8753655356d835422c230 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Wed, 25 Jul 2018 14:46:39 +0200 Subject: [PATCH 058/134] U4-10769 - Fix listviewhelper to work without key property on objects (#2521) --- .../common/services/listviewhelper.service.js | 23 +++++++++++++++---- .../src/less/components/umb-table.less | 4 ++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/listviewhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/listviewhelper.service.js index 2ffdc3f1dd..86553139c0 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/listviewhelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/listviewhelper.service.js @@ -270,12 +270,19 @@ for (var i = 0; selection.length > i; i++) { var selectedItem = selection[i]; // if item.id is 2147483647 (int.MaxValue) use item.key - if ((item.id !== 2147483647 && item.id === selectedItem.id) || item.key === selectedItem.key) { + if ((item.id !== 2147483647 && item.id === selectedItem.id) || (item.key && item.key === selectedItem.key)) { isSelected = true; } } if (!isSelected) { - selection.push({ id: item.id, key: item.key }); + var obj = { + id: item.id + }; + if (item.key) { + obj.key = item.key; + } + + selection.push(obj); item.selected = true; } } @@ -296,7 +303,7 @@ for (var i = 0; selection.length > i; i++) { var selectedItem = selection[i]; // if item.id is 2147483647 (int.MaxValue) use item.key - if ((item.id !== 2147483647 && item.id === selectedItem.id) || item.key === selectedItem.key) { + if ((item.id !== 2147483647 && item.id === selectedItem.id) || (item.key && item.key === selectedItem.key)) { selection.splice(i, 1); item.selected = false; } @@ -366,9 +373,15 @@ for (var i = 0; i < items.length; i++) { var item = items[i]; + var obj = { + id: item.id + }; + if (item.key) { + obj.key = item.key + } if (checkbox.checked) { - selection.push({ id: item.id, key: item.key }); + selection.push(obj); } else { clearSelection = true; } @@ -408,7 +421,7 @@ var selectedItem = selection[selectedIndex]; // if item.id is 2147483647 (int.MaxValue) use item.key - if ((item.id !== 2147483647 && item.id === selectedItem.id) || item.key === selectedItem.key) { + if ((item.id !== 2147483647 && item.id === selectedItem.id) || (item.key && item.key === selectedItem.key)) { numberOfSelectedItem++; } } diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less index 1bd2c5563d..7679fd3c24 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less @@ -93,7 +93,7 @@ input.umb-table__input { cursor: pointer; font-size: 14px; position: relative; - min-height: 32px; + min-height: 52px; &:hover { background-color: @gray-10; } @@ -271,4 +271,4 @@ input.umb-table__input { font-size: 20px; } -} \ No newline at end of file +} From 2669a51fe1f4e70f602767e338b06e1efa78e123 Mon Sep 17 00:00:00 2001 From: Dave Woestenborghs Date: Wed, 25 Jul 2018 16:01:33 +0300 Subject: [PATCH 059/134] Only show umbraco.tv and our.umbraco.org content to admin users in the help drawer (#2513) --- .../common/drawers/help/help.controller.js | 27 ++++++++++++------- .../src/views/common/drawers/help/help.html | 6 ++--- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.controller.js index 4d2b43c078..1f2daff083 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.controller.js @@ -43,15 +43,17 @@ setSectionName(); userService.getCurrentUser().then(function (user) { - + vm.userType = user.userType; vm.userLang = user.locale; + vm.hasAccessToSettings = _.contains(user.allowedSections, 'settings'); + evts.push(eventsService.on("appState.treeState.changed", function (e, args) { handleSectionChange(); })); - findHelp(vm.section, vm.tree, vm.usertype, vm.userLang); + findHelp(vm.section, vm.tree, vm.userType, vm.userLang); }); @@ -76,17 +78,20 @@ vm.tree = $routeParams.tree; setSectionName(); - findHelp(vm.section, vm.tree, vm.usertype, vm.userLang); + findHelp(vm.section, vm.tree, vm.userType, vm.userLang); } }); } function findHelp(section, tree, usertype, userLang) { + + if (vm.hasAccessToSettings) { + helpService.getContextHelpForPage(section, tree).then(function (topics) { + vm.topics = topics; + }); + } - helpService.getContextHelpForPage(section, tree).then(function (topics) { - vm.topics = topics; - }); var rq = {}; rq.section = vm.section; @@ -108,10 +113,12 @@ rq.path = rq.section + "/" + $routeParams.tree + "/" + $routeParams.method; } - helpService.findVideos(rq).then(function(videos){ - vm.videos = videos; - }); - + + if (vm.hasAccessToSettings) { + helpService.findVideos(rq).then(function (videos) { + vm.videos = videos; + }); + } } function setSectionName() { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.html b/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.html index a4d4af6093..7fb25df0d5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.html @@ -80,7 +80,7 @@
-
+
Videos
  • @@ -94,7 +94,7 @@
-
+
Visit umbraco.tv
@@ -128,4 +128,4 @@ - \ No newline at end of file + From 2bd9e24cc223088217d977afc95241210cb23cbc Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Wed, 25 Jul 2018 15:19:57 +0200 Subject: [PATCH 060/134] U4-9803 - Update styles of Repeatable textstrings (#2446) --- .../src/less/components/umb-node-preview.less | 10 +- .../src/less/property-editors.less | 1895 +++++++++-------- .../multipletextbox.controller.js | 2 +- .../multipletextbox/multipletextbox.html | 12 +- 4 files changed, 967 insertions(+), 952 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-node-preview.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-node-preview.less index 9e038bd571..3d1015f972 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-node-preview.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-node-preview.less @@ -1,11 +1,14 @@ .umb-node-preview { padding: 5px 0; display: flex; - max-width: 66.6%; box-sizing: border-box; border-bottom: 1px solid @gray-9; } +.umb-editor-wrapper .umb-node-preview { + max-width: 66.6%; +} + .umb-node-preview:last-of-type { border-bottom: none; } @@ -89,7 +92,6 @@ color: @turquoise-d1; font-weight: bold; padding: 5px 15px; - max-width: 66.6%; box-sizing: border-box; } @@ -97,6 +99,10 @@ color: @turquoise-d1; } +.umb-editor-wrapper .umb-node-preview-add { + max-width: 66.6%; +} + .umb-overlay, .umb-modal { .umb-node-preview { diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 3e408dfe38..116197d54d 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -1,943 +1,952 @@ -// -// Container styles -// -------------------------------------------------- -.umb-editor { - min-width:66.6%; - - &-pull { - float:left; - width:66.6%; - } - - &-push { - float:right; - } -} - -.umb-editor-tiny { - width: 60px; - - &.umb-editor-push { - width:30%; - min-width:0; - } -} - -.umb-editor-small { - width: 90px; -} - -.umb-modal .umb-editor { - width: 95%; -} - -.umb-dialog .umb-editor { - width: 95%; -} -.umb-dialog .umb-control-group .help-block { - width: 95%; -} - -.umb-codeeditor{ - width: 99%; -} - -// displays property inline with preceeding -.umb-property { - &--pull { - float:left; - width:60%; - } - - &--push { - float:right; - width:35%; - } - - &--pull, &--push { - .umb-editor { - min-width:0; - width:100%; - } - } -} - - -// -// Content picker -// -------------------------------------------------- -.umb-contentpicker li a:hover .hover-hide, .umb-contentpicker li a .hover-show{ - display: none; -} -.umb-contentpicker li a:hover .hover-show{display: inline-block;} - -.umb-contentpicker-popover .search-holder { - padding: 10px; -} - -.umb-contentpicker__min-max-help { - font-size: 13px; - margin-top: 5px; - color: @gray-4; -} - -.show-validation .umb-contentpicker__min-max-help { - display: none; -} - -.umb-contentpicker small { - - &:not(:last-child) { - padding-right: 3px; - border-right: 1px solid @gray-5; - } - - a { - color: @gray-3; - } -} - -/* CODEMIRROR DATATYPE */ -div.umb-codeeditor { - border: 1px solid @gray-8; -} -div.umb-codeeditor .umb-el-wrap { - padding: 0px; -} -div.umb-codeeditor .umb-btn-toolbar { - padding: 0px; - margin: 0px; - border-bottom: @gray-8 1px solid; - background: @gray-10; -} - - -// -// RTE -// -------------------------------------------------- -.mce-tinymce{border: 1px solid @gray-8 !important; border-radius: 0px !important;} -.mce-panel{background: @gray-10 !important; border-color: @gray-8 !important;} -.mce-btn-group, .mce-btn{border: none !important; background: none !important;} -.mce-ico{font-size: 12px !important; color: @gray-1 !important;} -/* Special case to support helviticons for the tiny mce button controls */ -.mce-ico.mce-i-custom[class^="icon-"], -.mce-ico.mce-i-custom[class*=" icon-"] { - font-family: icomoon; - font-size:16px !important; -} - -/* pre-value editor */ -.rte-editor-preval .control-group .controls > div > label .mce-ico { line-height: 20px; } - - -// -// Color picker -// -------------------------------------------------- -ul.color-picker li { - padding: 2px; - margin: 3px; - border: 2px solid transparent; - width: 60px; -} -ul.color-picker li.active { - border: 2px dashed @gray-8; -} -ul.color-picker li a { - height: 50px; - display:block; - cursor:pointer; -} - -.control-group.color-picker-preval .thumbnail { - width:30px; - border:none; -} - -/* pre-value editor */ -/*.control-group.color-picker-preval:before { - content: ""; - display: inline-block; - vertical-align: middle; - height: 100%; -}*/ - -/*.control-group.color-picker-preval div.thumbnail { - display: inline-block; - vertical-align: middle; -}*/ -.control-group.color-picker-preval div.color-picker-prediv { - display: inline-block; - width: 60%; -} - -.control-group.color-picker-preval pre { - display: inline; - margin-right: 20px; - margin-left: 10px; - width: 50%; - white-space: nowrap; - overflow: hidden; - margin-bottom: 0; - vertical-align: middle; -} - -.control-group.color-picker-preval btn { - //vertical-align: middle; -} - -.control-group.color-picker-preval input[type="text"] { - min-width: 40%; - width: 40%; - display: inline-block; - margin-right: 20px; - margin-top: 1px; -} - -.control-group.color-picker-preval label { - border: solid @white 1px; - padding: 6px; -} - - -// -// Media picker -// -------------------------------------------------- -.umb-mediapicker .add-link { - display: flex; - justify-content:center; - align-items:center; - width: 120px; - text-align: center; - color: @gray-8; - border: 2px @gray-8 dashed; - text-decoration: none; - - transition: all 150ms ease-in-out; - - &:hover { - color: @turquoise-d1; - border-color: @turquoise; - } -} - -.umb-mediapicker .picked-image { - position: absolute; - bottom: 10px; - right: 10px; - opacity: 0.5; - - font-size: 24px; - color: @red; - background: @white; - - line-height: 36px; - text-align: center; - -moz-border-radius: 15px; - border-radius: 15px; - - height: 32px; - width: 32px; - overflow: hidden; - display: none; - text-decoration: none; -} - -.umb-mediapicker .label.trashed { - position: absolute; - top: 5px; - right: 5px; - color: #fff; - background-color: #fe6561; - background-image: linear-gradient(180deg,#fe6561,#fe6561); -} - -.umb-mediapicker .add-link-square { - height: 120px; -} - - - -.umb-thumbnails { - position: relative; - display: flex; - -ms-flex-direction: row; - -webkit-flex-direction: row; - flex-direction: row; - -ms-flex-wrap: wrap; - -webkit-flex-wrap: wrap; - flex-wrap: wrap; - justify-content: flex-start; -} - -.umb-thumbnails > li.icon { - width: 14%; - text-align: center; -} - -.umb-thumbnails i{margin: auto;} -.umb-thumbnails a{ - outline: none; - border:none !important; - box-shadow:none !important; -} - - -.umb-sortable-thumbnails { - list-style-type: none; - margin: 0; - padding: 0; - display: flex; - flex-direction: row; - flex-wrap: wrap; -} - - -.umb-sortable-thumbnails li { - position: relative; - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - flex-wrap: wrap; - padding: 2px; - margin: 5px; - background: @white; - border: 1px solid @gray-10; - max-width: 100%; -} - - -.umb-mediapicker .umb-sortable-thumbnails li { - flex-direction: column; - margin: 0 5px 5px 0; - padding: 5px; -} - -.umb-sortable-thumbnails li:hover a { - display: flex; - justify-content: center; - align-items: center; -} - -.umb-sortable-thumbnails li img { - max-width:100%; - max-height:100%; - margin:auto; - display:block; - background-image: url(../img/checkered-background.png); -} - -.umb-sortable-thumbnails li img.trashed { - opacity:0.3; -} - -.umb-sortable-thumbnails li img.noScale { - max-width: none !important; - max-height: none !important; -} - -.umb-sortable-thumbnails .umb-icon-holder { - text-align: center; -} - -.umb-sortable-thumbnails .umb-icon-holder .icon{ - font-size: 40px; - line-height: 50px; - color: @gray-3; - display: block; -} - -.umb-sortable-thumbnails .umb-sortable-thumbnails__wrapper { - width: 124px; - height: 124px; - overflow: hidden; -} - -.umb-sortable-thumbnails .umb-sortable-thumbnails__actions { - position: absolute; - bottom: 10px; - right: 10px; - text-decoration: none; - display: flex; - flex-direction: row; - opacity: 0; - visibility: hidden; -} - -.umb-sortable-thumbnails.ui-sortable:not(.ui-sortable-disabled) { - > li:not(.unsortable) { - cursor: move; - } -} - -.umb-sortable-thumbnails li:hover .umb-sortable-thumbnails__actions { - opacity: 1; - visibility: visible; -} - -.umb-sortable-thumbnails .umb-sortable-thumbnails__action { - font-size: 16px; - background: @white; - height: 25px; - width: 25px; - border-radius: 15px; - color: @gray-1; - display: flex; - justify-content: center; - align-items: center; - margin-left: 5px; - text-decoration: none; -} - -.umb-sortable-thumbnails .umb-sortable-thumbnails__action.-red { - color: @red; -} - -.umb-sortable-thumbnails .umb-sortable-thumbnails__action:hover { - text-decoration: none; -} - - -// -// Cropper -// ------------------------------------------------- - -.umb-cropper{ - position: relative; -} - -.umb-cropper img, .umb-cropper-gravity img{ - position: relative; - max-width: 100%; - height: auto; - top: 0; - left: 0; - } - - .umb-cropper img { - max-width: none; - } - - .umb-cropper .overlay, .umb-cropper-gravity .overlay { - top: 0; - left: 0; - cursor: move; - z-index: @zindexCropperOverlay; - position: absolute; -} - -.umb-cropper .viewport{ - overflow: hidden; - position: relative; - margin: auto; - max-width: 100%; - height: auto; - } - -.umb-cropper-gravity .viewport{ - overflow: hidden; - position: relative; - width: 100%; - height: 100%; -} - - -.umb-cropper .viewport:after { - content: ""; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: @zindexCropperOverlay - 1; - -moz-opacity: .75; - opacity: .75; - filter: alpha(opacity=7); - -webkit-box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2); - -moz-box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2); - box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2); -} - -.umb-cropper-gravity .overlay{ - width: 14px; - height: 14px; - text-align: center; - border-radius: 20px; - background: @turquoise; - border: 3px solid @white; - opacity: 0.8; -} - -.umb-cropper-gravity .overlay i { - font-size: 26px; - line-height: 26px; - opacity: 0.8 !important; -} - -.umb-cropper .crop-container { - text-align: center; -} - -.umb-cropper .crop-slider { - padding: 10px; - border-top: 1px solid @gray-10; - margin-top: 10px; - display: flex; - align-items: center; - justify-content: center; - flex-wrap: wrap; - @media (min-width: 769px) { - padding: 10px 50px 10px 50px; - } -} - -.umb-cropper .crop-slider i { - color: @gray-3; - flex: 0 0 25px; - padding: 0 5px; - box-sizing: border-box; -} - -.umb-cropper .crop-slider i:first-of-type { - text-align: right; -} - -.umb-cropper .crop-slider input { - flex: 0 1 auto; -} - .umb-cropper-gravity .viewport, .umb-cropper-gravity, .umb-cropper-imageholder { - display: inline-block; - max-width: 100%; - } - - .umb-cropper-imageholder { - float: left; - } - - .cropList { - display: inline-block; - position: relative; - vertical-align: top; - } - - .gravity-container .viewport { - max-width: 600px; - } - - .gravity-container .viewport:hover { - cursor: pointer; - } - - .imagecropper { - display: flex; - align-items: flex-start; - flex-direction: row; - - @media (max-width: 768px) { - flex-direction: column; - float: left; - max-width: 100%; - } - } - - .imagecropper .umb-cropper__container { - position: relative; - margin-bottom: 10px; - max-width: 100%; - border: 1px solid @gray-10; - - @media (min-width: 769px) { - width: 600px; - } - } - - .umb-close-cropper { - position: absolute; - top: 3px; - right: 3px; - cursor: pointer; - z-index: 1; - } - - .umb-close-cropper:hover { - opacity: .9; - background: @gray-10; - } - - .imagecropper .umb-sortable-thumbnails { - display: flex; - flex-direction: row; - flex-wrap: wrap; - } - - .imagecropper .umb-sortable-thumbnails li { - display: flex; - flex-direction: column; - justify-content: space-between; - padding: 8px; - margin-top: 0; - } - - .imagecropper .umb-sortable-thumbnails li.current { - border-color: @gray-8; - background: @gray-10; - color: @black; - cursor: pointer; - } - - .imagecropper .umb-sortable-thumbnails li:hover, - .imagecropper .umb-sortable-thumbnails li.current:hover { - border-color: @gray-8; - background: @gray-10; - color: @black; - cursor: pointer; - opacity: .95; - } - - .imagecropper .umb-sortable-thumbnails li .crop-name, - .imagecropper .umb-sortable-thumbnails li .crop-size { - display: block; - text-align: left; - font-size: 13px; - line-height: 1; - } - - .imagecropper .umb-sortable-thumbnails li .crop-name { - font-weight: bold; - margin: 10px 0 5px; - } - - .imagecropper .umb-sortable-thumbnails li .crop-size { - font-size: 10px; - font-style: italic; - margin: 0 0 5px; - } - - .btn-crop-delete { - display: block; - text-align: left; - } - -// -// folder-browser -// -------------------------------------------------- -.umb-folderbrowser .add-link{ - display: inline-block; - height: 120px; - width: 120px; - text-align: center; - border: 1px @gray-10 dashed; - line-height: 120px -} - -.umb-upload-drop-zone{ - margin-bottom:5px; -} - -.umb-upload-drop-zone .info, .umb-upload-button-big{ - display: block; - padding: 20px; - opacity: 1; - border: 1px dashed @gray-8; - background: none; - text-align: center; - font-size: 14px; - color: @gray-8; -} - -.umb-upload-button-big:hover{color: @gray-8;} - -.umb-upload-drop-zone .info i.icon, .umb-upload-button-big i.icon{ - font-size: 55px; - line-height: 70px -} - -.umb-upload-button-big {display: block} -.umb-upload-button-big input { - left: 0; - bottom: 0; - height: 100%; - width: 100%; -} - - - -// -// Photo folder styling -// -------------------------------------------------- - -.umb-photo-folder .picrow{ - overflow-y: hidden; - position: relative; -} - - - -.umb-photo-folder .picrow div, .umb-photo-preview{ - margin: 0px; - padding: 0px; - border: none; - display: inline-block; - vertical-align: top; - position: relative; -} - - - -.umb-photo-folder .picrow div a:first-child { - width:100%; - height:100%; -} - -.umb-photo-folder .picrow div.umb-photo { - width:100%; - height:100%; - background-color: @gray-10; -} - -.umb-photo-folder a:hover{text-decoration: none} -.umb-photo-folder .umb-non-thumbnail{ - text-align: center; - vertical-align: middle; - font-size: 12px; - background: @gray-10; - color: @black; - text-decoration: none; -} - -.umb-photo-folder .selector-overlay{ - display: none; -} - -//this is a temp hack, to provide selectors in the dialog: -.umb-photo-folder .pic:hover .selector-overlay { - position: absolute; - bottom: 0px; - left: 0px; - right: 0px; - padding: 5px; - background: @black; - z-index: 100; - display: block; - text-align: center; - color: @white; - opacity: 0.4; - text-decoration:none; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.umb-photo-folder .umb-non-thumbnail i{ - color: @gray-8; - font-size: 50px; - line-height: 60px; - display: block; - margin: auto; - /*vertically aligns */ - position: relative; - top: 50%; - transform: translateY(-50%); -} - -.umb-photo-folder .umb-non-thumbnail span{ - position: absolute; - display: block; - margin: auto; - width: 100%; - top: 20px; -} - -.umb-photo-folder .selected{ - position: relative; -} - -.umb-photo-folder .selected:before{ - content: "\e165"; - font-family: Icomoon; - - position: absolute; - bottom: 10px; - right: 10px; - - font-size: 24px; - color: @black; - opacity: 0.5; - background: @white; - - line-height: 36px; - text-align: center; - -moz-border-radius: 15px; - border-radius: 15px; - - height: 32px; - width: 32px; - overflow: hidden; - display: block; - z-index: 100; -} - - -// -// File upload -// -------------------------------------------------- -.umb-fileupload .preview { - border-radius: 5px; - border: 1px solid @gray-6; - padding: 3px; - background: @gray-9; - float: left; - margin-right: 30px; - margin-bottom: 30px; -} - -.umb-fileupload ul { - list-style: none; - vertical-align: middle; - margin-bottom: 0px; -} - -.umb-fileupload label { - vertical-align: middle; - padding-left: 7px; - font-weight: normal; -} - -.umb-fileupload .preview-file { - color: @gray-4; - height: 45px; - width: 55px; - text-align: center; - text-transform: uppercase; - font-size: 10px; - padding-top: 27px; -} - -.umb-fileupload .file-icon { - text-align: center; - display: block; - position: relative; - padding: 5px 0; - - > .icon { - font-size: 70px; - line-height: 110%; - color: @gray-4; - text-align: center; - } - - > span { - color: @white; - background: @gray-4; - padding: 1px 3px; - font-size: 12px; - line-height: 130%; - position: absolute; - top: 45px; - left: 110px; - } -} - -.umb-fileupload input { - font-size: 12px; - line-height: 1; -} - -// -// Member group picker -// -------------------------------------------------- - -.umb-member-group-box { - width: 45%; -} -.umb-member-group-box:nth-child(1){ - float:left; -} -.umb-member-group-box:nth-child(2){ - float:right; -} - -// -// Related links -// -------------------------------------------------- -.umb-relatedlinks table > tr > td { word-wrap:break-word; word-break: break-all; border-bottom: 1px solid transparent; } -.umb-relatedlinks .handle { cursor:move; } -.umb-relatedlinks table > tbody > tr.unsortable .handle { cursor:default; } - -.umb-relatedlinks table td.col-sort { width: 20px; } -.umb-relatedlinks table td.col-caption { min-width: 200px; } -.umb-relatedlinks table td.col-link { min-width: 200px; } -.umb-relatedlinks table td.col-actions { min-width: 120px; } - -.umb-relatedlinks table td.col-caption .control-wrapper, -.umb-relatedlinks table td.col-link .control-wrapper { display: flex; } - -.umb-relatedlinks table td.col-caption .control-wrapper input[type="text"], -.umb-relatedlinks table td.col-link .control-wrapper input[type="text"] { width: auto; flex: 1; } - -/* sortable placeholder */ -.umb-relatedlinks .sortable-placeholder { - background-color: @tableBackgroundAccent; - display: table-row; -} -.umb-relatedlinks .sortable-placeholder > td { - display: table-cell; - padding: 8px; -} -.umb-relatedlinks .ui-sortable-helper { - display: table-row; - background-color: @white; - opacity: 0.7; -} -.umb-relatedlinks .ui-sortable-helper > td { - display: table-cell; - border-bottom: 1px solid @tableBorder; -} - - -// -// Tags -// -------------------------------------------------- -.umb-tags{border: @gray-10 solid 1px; padding: 10px; font-size: 13px; text-shadow: none;} -.umb-tags .tag{cursor: pointer; margin: 7px; padding: 7px; background: @turquoise} -.umb-tags .tag i{padding: 2px;} -.umb-tags input{border: none; background: @white} - -// -// Date/time picker -// -------------------------------------------------- -.bootstrap-datetimepicker-widget .btn{padding: 0;} -.bootstrap-datetimepicker-widget .picker-switch .btn{ background: none; border: none;} -.umb-datepicker .input-append .add-on{cursor: pointer;} -.umb-datepicker p {margin-top:10px;} -.umb-datepicker p a{color: @gray-3;} - -// -// Code mirror - even though this isn't a proprety editor right now, it could be so I'm putting the styles here -// -------------------------------------------------- - -.CodeMirror, .CodeMirror-scroll { - height: 100%; - min-height:200px; -} - -// -// Nested boolean (e.g. list view bulk action permissions) -// ------------------------------------------------------- -.umb-nested-boolean label {margin-bottom: 8px; float: left; width: 320px;} -.umb-nested-boolean label span {float: left; width: 80%;} -.umb-nested-boolean label input[type='checkbox'] {margin-right: 10px; float: left;} - - -// -// Custom styles of property editors in property preview in document type editor -// ----------------------------------------------------------------------------- -.umb-group-builder__property-preview { - .umb-property-editor { - .slider { - .tooltip { - display: none; - } - } - } -} +// +// Container styles +// -------------------------------------------------- +.umb-editor { + min-width:66.6%; + + &-pull { + float:left; + width:66.6%; + } + + &-push { + float:right; + } +} + +.umb-editor-tiny { + width: 60px; + + &.umb-editor-push { + width:30%; + min-width:0; + } +} + +.umb-editor-small { + width: 90px; +} + +.umb-modal .umb-editor { + width: 95%; +} + +.umb-dialog .umb-editor { + width: 95%; +} +.umb-dialog .umb-control-group .help-block { + width: 95%; +} + +.umb-codeeditor{ + width: 99%; +} + +// displays property inline with preceeding +.umb-property { + &--pull { + float:left; + width:60%; + } + + &--push { + float:right; + width:35%; + } + + &--pull, &--push { + .umb-editor { + min-width:0; + width:100%; + } + } +} + + +// +// Content picker +// -------------------------------------------------- +.umb-contentpicker li a:hover .hover-hide, .umb-contentpicker li a .hover-show{ + display: none; +} +.umb-contentpicker li a:hover .hover-show{display: inline-block;} + +.umb-contentpicker-popover .search-holder { + padding: 10px; +} + +.umb-contentpicker__min-max-help { + font-size: 13px; + margin-top: 5px; + color: @gray-4; +} + +.show-validation .umb-contentpicker__min-max-help { + display: none; +} + +.umb-contentpicker small { + + &:not(:last-child) { + padding-right: 3px; + border-right: 1px solid @gray-5; + } + + a { + color: @gray-3; + } +} + +/* CODEMIRROR DATATYPE */ +div.umb-codeeditor { + border: 1px solid @gray-8; +} +div.umb-codeeditor .umb-el-wrap { + padding: 0px; +} +div.umb-codeeditor .umb-btn-toolbar { + padding: 0px; + margin: 0px; + border-bottom: @gray-8 1px solid; + background: @gray-10; +} + + +// +// RTE +// -------------------------------------------------- +.mce-tinymce{border: 1px solid @gray-8 !important; border-radius: 0px !important;} +.mce-panel{background: @gray-10 !important; border-color: @gray-8 !important;} +.mce-btn-group, .mce-btn{border: none !important; background: none !important;} +.mce-ico{font-size: 12px !important; color: @gray-1 !important;} +/* Special case to support helviticons for the tiny mce button controls */ +.mce-ico.mce-i-custom[class^="icon-"], +.mce-ico.mce-i-custom[class*=" icon-"] { + font-family: icomoon; + font-size:16px !important; +} + +/* pre-value editor */ +.rte-editor-preval .control-group .controls > div > label .mce-ico { line-height: 20px; } + + +// +// Color picker +// -------------------------------------------------- +ul.color-picker li { + padding: 2px; + margin: 3px; + border: 2px solid transparent; + width: 60px; +} +ul.color-picker li.active { + border: 2px dashed @gray-8; +} +ul.color-picker li a { + height: 50px; + display:block; + cursor:pointer; +} + +.control-group.color-picker-preval .thumbnail { + width:30px; + border:none; +} + +/* pre-value editor */ +/*.control-group.color-picker-preval:before { + content: ""; + display: inline-block; + vertical-align: middle; + height: 100%; +}*/ + +/*.control-group.color-picker-preval div.thumbnail { + display: inline-block; + vertical-align: middle; +}*/ +.control-group.color-picker-preval div.color-picker-prediv { + display: inline-block; + width: 60%; +} + +.control-group.color-picker-preval pre { + display: inline; + margin-right: 20px; + margin-left: 10px; + width: 50%; + white-space: nowrap; + overflow: hidden; + margin-bottom: 0; + vertical-align: middle; +} + +.control-group.color-picker-preval input[type="text"] { + min-width: 40%; + width: 40%; + display: inline-block; + margin-right: 20px; + margin-top: 1px; +} + +.control-group.color-picker-preval label { + border: solid @white 1px; + padding: 6px; +} + + +// +// Media picker +// -------------------------------------------------- +.umb-mediapicker .add-link { + display: flex; + justify-content:center; + align-items:center; + width: 120px; + text-align: center; + color: @gray-8; + border: 2px @gray-8 dashed; + text-decoration: none; + + transition: all 150ms ease-in-out; + + &:hover { + color: @turquoise-d1; + border-color: @turquoise; + } +} + +.umb-mediapicker .picked-image { + position: absolute; + bottom: 10px; + right: 10px; + opacity: 0.5; + + font-size: 24px; + color: @red; + background: @white; + + line-height: 36px; + text-align: center; + -moz-border-radius: 15px; + border-radius: 15px; + + height: 32px; + width: 32px; + overflow: hidden; + display: none; + text-decoration: none; +} + +.umb-mediapicker .label.trashed { + position: absolute; + top: 5px; + right: 5px; + color: #fff; + background-color: #fe6561; + background-image: linear-gradient(180deg,#fe6561,#fe6561); +} + +.umb-mediapicker .add-link-square { + height: 120px; +} + + + +.umb-thumbnails { + position: relative; + display: flex; + -ms-flex-direction: row; + -webkit-flex-direction: row; + flex-direction: row; + -ms-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + flex-wrap: wrap; + justify-content: flex-start; +} + +.umb-thumbnails > li.icon { + width: 14%; + text-align: center; +} + +.umb-thumbnails i{margin: auto;} +.umb-thumbnails a{ + outline: none; + border:none !important; + box-shadow:none !important; +} + + +.umb-sortable-thumbnails { + list-style-type: none; + margin: 0; + padding: 0; + display: flex; + flex-direction: row; + flex-wrap: wrap; +} + + +.umb-sortable-thumbnails li { + position: relative; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + flex-wrap: wrap; + padding: 2px; + margin: 5px; + background: @white; + border: 1px solid @gray-10; + max-width: 100%; +} + + +.umb-mediapicker .umb-sortable-thumbnails li { + flex-direction: column; + margin: 0 5px 5px 0; + padding: 5px; +} + +.umb-sortable-thumbnails li:hover a { + display: flex; + justify-content: center; + align-items: center; +} + +.umb-sortable-thumbnails li img { + max-width:100%; + max-height:100%; + margin:auto; + display:block; + background-image: url(../img/checkered-background.png); +} + +.umb-sortable-thumbnails li img.trashed { + opacity:0.3; +} + +.umb-sortable-thumbnails li img.noScale { + max-width: none !important; + max-height: none !important; +} + +.umb-sortable-thumbnails .umb-icon-holder { + text-align: center; +} + +.umb-sortable-thumbnails .umb-icon-holder .icon{ + font-size: 40px; + line-height: 50px; + color: @gray-3; + display: block; +} + +.umb-sortable-thumbnails .umb-sortable-thumbnails__wrapper { + width: 124px; + height: 124px; + overflow: hidden; +} + +.umb-sortable-thumbnails .umb-sortable-thumbnails__actions { + position: absolute; + bottom: 10px; + right: 10px; + text-decoration: none; + display: flex; + flex-direction: row; + opacity: 0; + visibility: hidden; +} + +.umb-sortable-thumbnails.ui-sortable:not(.ui-sortable-disabled) { + > li:not(.unsortable) { + cursor: move; + } +} + +.umb-sortable-thumbnails li:hover .umb-sortable-thumbnails__actions { + opacity: 1; + visibility: visible; +} + +.umb-sortable-thumbnails .umb-sortable-thumbnails__action { + font-size: 16px; + background: @white; + height: 25px; + width: 25px; + border-radius: 15px; + color: @gray-1; + display: flex; + justify-content: center; + align-items: center; + margin-left: 5px; + text-decoration: none; +} + +.umb-sortable-thumbnails .umb-sortable-thumbnails__action.-red { + color: @red; +} + +.umb-sortable-thumbnails .umb-sortable-thumbnails__action:hover { + text-decoration: none; +} + + +// +// Cropper +// ------------------------------------------------- + +.umb-cropper{ + position: relative; +} + +.umb-cropper img, .umb-cropper-gravity img{ + position: relative; + max-width: 100%; + height: auto; + top: 0; + left: 0; + } + + .umb-cropper img { + max-width: none; + } + + .umb-cropper .overlay, .umb-cropper-gravity .overlay { + top: 0; + left: 0; + cursor: move; + z-index: @zindexCropperOverlay; + position: absolute; +} + +.umb-cropper .viewport{ + overflow: hidden; + position: relative; + margin: auto; + max-width: 100%; + height: auto; + } + +.umb-cropper-gravity .viewport{ + overflow: hidden; + position: relative; + width: 100%; + height: 100%; +} + + +.umb-cropper .viewport:after { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: @zindexCropperOverlay - 1; + -moz-opacity: .75; + opacity: .75; + filter: alpha(opacity=7); + -webkit-box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2); + -moz-box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2); + box-shadow: inset 0 0 0 20px white,inset 0 0 0 21px rgba(0,0,0,.1),inset 0 0 20px 21px rgba(0,0,0,.2); +} + +.umb-cropper-gravity .overlay{ + width: 14px; + height: 14px; + text-align: center; + border-radius: 20px; + background: @turquoise; + border: 3px solid @white; + opacity: 0.8; +} + +.umb-cropper-gravity .overlay i { + font-size: 26px; + line-height: 26px; + opacity: 0.8 !important; +} + +.umb-cropper .crop-container { + text-align: center; +} + +.umb-cropper .crop-slider { + padding: 10px; + border-top: 1px solid @gray-10; + margin-top: 10px; + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + @media (min-width: 769px) { + padding: 10px 50px 10px 50px; + } +} + +.umb-cropper .crop-slider i { + color: @gray-3; + flex: 0 0 25px; + padding: 0 5px; + box-sizing: border-box; +} + +.umb-cropper .crop-slider i:first-of-type { + text-align: right; +} + +.umb-cropper .crop-slider input { + flex: 0 1 auto; +} + .umb-cropper-gravity .viewport, .umb-cropper-gravity, .umb-cropper-imageholder { + display: inline-block; + max-width: 100%; + } + + .umb-cropper-imageholder { + float: left; + } + + .cropList { + display: inline-block; + position: relative; + vertical-align: top; + } + + .gravity-container .viewport { + max-width: 600px; + } + + .gravity-container .viewport:hover { + cursor: pointer; + } + + .imagecropper { + display: flex; + align-items: flex-start; + flex-direction: row; + + @media (max-width: 768px) { + flex-direction: column; + float: left; + max-width: 100%; + } + } + + .imagecropper .umb-cropper__container { + position: relative; + margin-bottom: 10px; + max-width: 100%; + border: 1px solid @gray-10; + + @media (min-width: 769px) { + width: 600px; + } + } + + .umb-close-cropper { + position: absolute; + top: 3px; + right: 3px; + cursor: pointer; + z-index: 1; + } + + .umb-close-cropper:hover { + opacity: .9; + background: @gray-10; + } + + .imagecropper .umb-sortable-thumbnails { + display: flex; + flex-direction: row; + flex-wrap: wrap; + } + + .imagecropper .umb-sortable-thumbnails li { + display: flex; + flex-direction: column; + justify-content: space-between; + padding: 8px; + margin-top: 0; + } + + .imagecropper .umb-sortable-thumbnails li.current { + border-color: @gray-8; + background: @gray-10; + color: @black; + cursor: pointer; + } + + .imagecropper .umb-sortable-thumbnails li:hover, + .imagecropper .umb-sortable-thumbnails li.current:hover { + border-color: @gray-8; + background: @gray-10; + color: @black; + cursor: pointer; + opacity: .95; + } + + .imagecropper .umb-sortable-thumbnails li .crop-name, + .imagecropper .umb-sortable-thumbnails li .crop-size { + display: block; + text-align: left; + font-size: 13px; + line-height: 1; + } + + .imagecropper .umb-sortable-thumbnails li .crop-name { + font-weight: bold; + margin: 10px 0 5px; + } + + .imagecropper .umb-sortable-thumbnails li .crop-size { + font-size: 10px; + font-style: italic; + margin: 0 0 5px; + } + + .btn-crop-delete { + display: block; + text-align: left; + } + +// +// folder-browser +// -------------------------------------------------- +.umb-folderbrowser .add-link{ + display: inline-block; + height: 120px; + width: 120px; + text-align: center; + border: 1px @gray-10 dashed; + line-height: 120px +} + +.umb-upload-drop-zone{ + margin-bottom:5px; +} + +.umb-upload-drop-zone .info, .umb-upload-button-big{ + display: block; + padding: 20px; + opacity: 1; + border: 1px dashed @gray-8; + background: none; + text-align: center; + font-size: 14px; + color: @gray-8; +} + +.umb-upload-button-big:hover{color: @gray-8;} + +.umb-upload-drop-zone .info i.icon, .umb-upload-button-big i.icon{ + font-size: 55px; + line-height: 70px +} + +.umb-upload-button-big {display: block} +.umb-upload-button-big input { + left: 0; + bottom: 0; + height: 100%; + width: 100%; +} + + + +// +// Photo folder styling +// -------------------------------------------------- + +.umb-photo-folder .picrow{ + overflow-y: hidden; + position: relative; +} + + + +.umb-photo-folder .picrow div, .umb-photo-preview{ + margin: 0px; + padding: 0px; + border: none; + display: inline-block; + vertical-align: top; + position: relative; +} + + + +.umb-photo-folder .picrow div a:first-child { + width:100%; + height:100%; +} + +.umb-photo-folder .picrow div.umb-photo { + width:100%; + height:100%; + background-color: @gray-10; +} + +.umb-photo-folder a:hover{text-decoration: none} +.umb-photo-folder .umb-non-thumbnail{ + text-align: center; + vertical-align: middle; + font-size: 12px; + background: @gray-10; + color: @black; + text-decoration: none; +} + +.umb-photo-folder .selector-overlay{ + display: none; +} + +//this is a temp hack, to provide selectors in the dialog: +.umb-photo-folder .pic:hover .selector-overlay { + position: absolute; + bottom: 0px; + left: 0px; + right: 0px; + padding: 5px; + background: @black; + z-index: 100; + display: block; + text-align: center; + color: @white; + opacity: 0.4; + text-decoration:none; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.umb-photo-folder .umb-non-thumbnail i{ + color: @gray-8; + font-size: 50px; + line-height: 60px; + display: block; + margin: auto; + /*vertically aligns */ + position: relative; + top: 50%; + transform: translateY(-50%); +} + +.umb-photo-folder .umb-non-thumbnail span{ + position: absolute; + display: block; + margin: auto; + width: 100%; + top: 20px; +} + +.umb-photo-folder .selected{ + position: relative; +} + +.umb-photo-folder .selected:before{ + content: "\e165"; + font-family: Icomoon; + + position: absolute; + bottom: 10px; + right: 10px; + + font-size: 24px; + color: @black; + opacity: 0.5; + background: @white; + + line-height: 36px; + text-align: center; + -moz-border-radius: 15px; + border-radius: 15px; + + height: 32px; + width: 32px; + overflow: hidden; + display: block; + z-index: 100; +} + + +// +// File upload +// -------------------------------------------------- +.umb-fileupload .preview { + border-radius: 5px; + border: 1px solid @gray-6; + padding: 3px; + background: @gray-9; + float: left; + margin-right: 30px; + margin-bottom: 30px; +} + +.umb-fileupload ul { + list-style: none; + vertical-align: middle; + margin-bottom: 0px; +} + +.umb-fileupload label { + vertical-align: middle; + padding-left: 7px; + font-weight: normal; +} + +.umb-fileupload .preview-file { + color: @gray-4; + height: 45px; + width: 55px; + text-align: center; + text-transform: uppercase; + font-size: 10px; + padding-top: 27px; +} + +.umb-fileupload .file-icon { + text-align: center; + display: block; + position: relative; + padding: 5px 0; + + > .icon { + font-size: 70px; + line-height: 110%; + color: @gray-4; + text-align: center; + } + + > span { + color: @white; + background: @gray-4; + padding: 1px 3px; + font-size: 12px; + line-height: 130%; + position: absolute; + top: 45px; + left: 110px; + } +} + +.umb-fileupload input { + font-size: 12px; + line-height: 1; +} + +// +// Member group picker +// -------------------------------------------------- + +.umb-member-group-box { + width: 45%; +} +.umb-member-group-box:nth-child(1){ + float:left; +} +.umb-member-group-box:nth-child(2){ + float:right; +} + +// +// Related links +// -------------------------------------------------- +.umb-relatedlinks table > tr > td { word-wrap:break-word; word-break: break-all; border-bottom: 1px solid transparent; } +.umb-relatedlinks .handle { cursor:move; } +.umb-relatedlinks table > tbody > tr.unsortable .handle { cursor:default; } + +.umb-relatedlinks table td.col-sort { width: 20px; } +.umb-relatedlinks table td.col-caption { min-width: 200px; } +.umb-relatedlinks table td.col-link { min-width: 200px; } +.umb-relatedlinks table td.col-actions { min-width: 120px; } + +.umb-relatedlinks table td.col-caption .control-wrapper, +.umb-relatedlinks table td.col-link .control-wrapper { display: flex; } + +.umb-relatedlinks table td.col-caption .control-wrapper input[type="text"], +.umb-relatedlinks table td.col-link .control-wrapper input[type="text"] { width: auto; flex: 1; } + +/* sortable placeholder */ +.umb-relatedlinks .sortable-placeholder { + background-color: @tableBackgroundAccent; + display: table-row; +} +.umb-relatedlinks .sortable-placeholder > td { + display: table-cell; + padding: 8px; +} +.umb-relatedlinks .ui-sortable-helper { + display: table-row; + background-color: @white; + opacity: 0.7; +} +.umb-relatedlinks .ui-sortable-helper > td { + display: table-cell; + border-bottom: 1px solid @tableBorder; +} + +.umb-multiple-textbox .textbox-wrapper { align-items: center; margin-bottom: 15px; } +.umb-multiple-textbox .textbox-wrapper .umb-editor { margin-bottom: 0; } +.umb-multiple-textbox .textbox-wrapper i { margin-right: 5px; } +.umb-multiple-textbox .textbox-wrapper i.handle { margin-left: 5px; } +.umb-multiple-textbox .textbox-wrapper a.remove { margin-left: 5px; text-decoration: none; } +.umb-multiple-textbox .add-link { + &:extend(.umb-node-preview-add); +} +.umb-editor-wrapper .umb-multiple-textbox .add-link { + &:extend(.umb-editor-wrapper .umb-node-preview); +} +.umb-modal .umb-multiple-textbox .textbox-wrapper .umb-editor { flex: 1 1 auto; width: auto; } + + +// +// Tags +// -------------------------------------------------- +.umb-tags{border: @gray-10 solid 1px; padding: 10px; font-size: 13px; text-shadow: none;} +.umb-tags .tag{cursor: pointer; margin: 7px; padding: 7px; background: @turquoise} +.umb-tags .tag i{padding: 2px;} +.umb-tags input{border: none; background: @white} + +// +// Date/time picker +// -------------------------------------------------- +.bootstrap-datetimepicker-widget .btn{padding: 0;} +.bootstrap-datetimepicker-widget .picker-switch .btn{ background: none; border: none;} +.umb-datepicker .input-append .add-on{cursor: pointer;} +.umb-datepicker p {margin-top:10px;} +.umb-datepicker p a{color: @gray-3;} + +// +// Code mirror - even though this isn't a proprety editor right now, it could be so I'm putting the styles here +// -------------------------------------------------- + +.CodeMirror, .CodeMirror-scroll { + height: 100%; + min-height:200px; +} + +// +// Nested boolean (e.g. list view bulk action permissions) +// ------------------------------------------------------- +.umb-nested-boolean label {margin-bottom: 8px; float: left; width: 320px;} +.umb-nested-boolean label span {float: left; width: 80%;} +.umb-nested-boolean label input[type='checkbox'] {margin-right: 10px; float: left;} + + +// +// Custom styles of property editors in property preview in document type editor +// ----------------------------------------------------------------------------- +.umb-group-builder__property-preview { + .umb-property-editor { + .slider { + .tooltip { + display: none; + } + } + } +} diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.controller.js index 3e15fb7541..acee0f5ce9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.controller.js @@ -6,7 +6,7 @@ axis: 'y', containment: 'parent', cursor: 'move', - items: '> div.control-group', + items: '> div.textbox-wrapper', tolerance: 'pointer' }; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html index 7a6b4f4a29..123385d681 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html @@ -1,21 +1,21 @@
From 187a32cdc03afe4e8cb56d0ef61018577c77042a Mon Sep 17 00:00:00 2001 From: Anders Bjerner Date: Wed, 25 Jul 2018 16:01:36 +0200 Subject: [PATCH 061/134] Added fallback URLs for the "umbNodePreview" directive (#2369) --- .../content/umbcontentnodeinfo.directive.js | 3 +++ .../components/umbnodepreview.directive.js | 10 ++++++++-- .../components/content/umb-content-node-info.html | 13 +++++++------ .../src/views/components/umb-node-preview.html | 6 +++--- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js index e9cc3c6946..fd8ce14441 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js @@ -41,6 +41,9 @@ // make sure dates are formatted to the user's locale formatDatesToLocal(); + // Declare a fallback URL for the directive + scope.previewOpenUrl = '#/settings/documenttypes/edit/' + scope.documentType.id; + setNodePublishStatus(scope.node); } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbnodepreview.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbnodepreview.directive.js index 21714d172c..9f1f7a0d2e 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbnodepreview.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbnodepreview.directive.js @@ -88,6 +88,9 @@ @param {function} onRemove (expression): Callback function when the remove button is clicked. @param {function} onOpen (expression): Callback function when the open button is clicked. @param {function} onEdit (expression): Callback function when the edit button is clicked (Added in version 7.7.0). +@param {string} openUrl (binding): Fallback URL for onOpen (Added in version 7.12.0). +@param {string} editUrl (binding): Fallback URL for onEdit (Added in version 7.12.0). +@param {string} removeUrl (binding): Fallback URL for onRemove (Added in version 7.12.0). **/ (function () { @@ -122,7 +125,10 @@ allowEdit: "=?", onOpen: "&?", onRemove: "&?", - onEdit: "&?" + onEdit: "&?", + openUrl: '=?', + editUrl: '=?', + removeUrl: '=?' }, link: link }; @@ -133,4 +139,4 @@ angular.module('umbraco.directives').directive('umbNodePreview', NodePreviewDirective); -})(); \ No newline at end of file +})(); diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html index 783ceb262b..4bd73b4ccd 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html @@ -176,12 +176,13 @@ - + diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-node-preview.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-node-preview.html index 2d3d2cfdae..ca7a30f152 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-node-preview.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-node-preview.html @@ -13,9 +13,9 @@
- Edit - Open - Remove + Edit + Open + Remove
From 02ac44e214c7d6cd1f9e630b1fe8e731f0449a16 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Wed, 25 Jul 2018 16:29:20 +0200 Subject: [PATCH 062/134] U4-10792 - highlight error when trying to add duplicate in listview columns (#2362) --- .../includeproperties.prevalues.controller.js | 45 ++++++++++++++----- .../listview/includeproperties.prevalues.html | 3 +- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js index 0cd199ae4d..216f1555e2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js @@ -4,6 +4,9 @@ function includePropsPreValsController($rootScope, $scope, localizationService, $scope.model.value = []; } + $scope.hasError = false; + $scope.errorMsg = ""; + $scope.propertyAliases = []; $scope.selectedField = null; $scope.systemFields = [ @@ -45,6 +48,11 @@ function includePropsPreValsController($rootScope, $scope, localizationService, return alias; } + $scope.changeField = function () { + $scope.hasError = false; + $scope.errorMsg = ""; + } + $scope.removeField = function(e) { $scope.model.value = _.reject($scope.model.value, function (x) { return x.alias === e.alias; @@ -123,19 +131,34 @@ function includePropsPreValsController($rootScope, $scope, localizationService, $scope.addField = function () { var val = $scope.selectedField; - var isSystem = val.startsWith("_system_"); - if (isSystem) { - val = val.trimStart("_system_"); - } + if (val) { + var isSystem = val.startsWith("_system_"); + if (isSystem) { + val = val.trimStart("_system_"); + } - var exists = _.find($scope.model.value, function (i) { - return i.alias === val; - }); - if (!exists) { - $scope.model.value.push({ - alias: val, - isSystem: isSystem ? 1 : 0 + var exists = _.find($scope.model.value, function (i) { + return i.alias === val; }); + + if (!exists) { + $scope.hasError = false; + $scope.errorMsg = ""; + + $scope.model.value.push({ + alias: val, + isSystem: isSystem ? 1 : 0 + }); + } + else { + //there was an error, do the highlight (will be set back by the directive) + $scope.hasError = true; + $scope.errorMsg = "Property is already added"; + } + } + else { + $scope.hasError = true; + $scope.errorMsg = "No property selected"; } } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.html index 2e210e635f..749d5b5cb0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.html @@ -1,7 +1,7 @@ 
- @@ -9,6 +9,7 @@ + {{errorMsg}}
From 0eddf6b75532e20a6420d538c79e89cfe109674f Mon Sep 17 00:00:00 2001 From: Owain Williams Date: Thu, 26 Jul 2018 09:04:55 +0100 Subject: [PATCH 063/134] Implementing new colour picker for document types (#2792) --- .../components/umbcolorswatches.directive.js | 61 ++ src/Umbraco.Web.UI.Client/src/less/belle.less | 1 + .../less/components/umb-color-swatches.less | 61 ++ .../src/less/components/umb-iconpicker.less | 36 + .../src/less/variables.less | 951 ++++++++++-------- .../iconpicker/iconpicker.controller.js | 62 +- .../overlays/iconpicker/iconpicker.html | 24 +- .../views/components/umb-color-swatches.html | 9 + 8 files changed, 729 insertions(+), 476 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/common/directives/components/umbcolorswatches.directive.js create mode 100644 src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less create mode 100644 src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbcolorswatches.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbcolorswatches.directive.js new file mode 100644 index 0000000000..6ed65a9431 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbcolorswatches.directive.js @@ -0,0 +1,61 @@ + +/** +@ngdoc directive +@name umbraco.directives.directive:umbColorSwatches +@restrict E +@scope +@description +Use this directive to generate color swatches to pick from. +

Markup example

+
+    
+    
+
+@param {array} colors (attribute): The array of colors. +@param {string} colors (attribute): The array of colors. +@param {string} selectedColor (attribute): The selected color. +@param {string} size (attribute): The size (s, m). +@param {function} onSelect (expression): Callback function when the item is selected. +**/ + +(function () { + 'use strict'; + + function ColorSwatchesDirective() { + + function link(scope, el, attr, ctrl) { + + scope.setColor = function (color) { + //scope.selectedColor({color: color }); + scope.selectedColor = color; + + if (scope.onSelect) { + scope.onSelect(color); + } + }; + } + + var directive = { + restrict: 'E', + replace: true, + transclude: true, + templateUrl: 'views/components/umb-color-swatches.html', + scope: { + colors: '=?', + size: '@', + selectedColor: '=', + onSelect: '&' + }, + link: link + }; + + return directive; + + } + + angular.module('umbraco.directives').directive('umbColorSwatches', ColorSwatchesDirective); + +})(); diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less index 90521e1ec7..5fc9a48e47 100644 --- a/src/Umbraco.Web.UI.Client/src/less/belle.less +++ b/src/Umbraco.Web.UI.Client/src/less/belle.less @@ -114,6 +114,7 @@ @import "components/umb-grid.less"; @import "components/umb-empty-state.less"; @import "components/umb-property-editor.less"; +@import "components/umb-color-swatches.less"; @import "components/umb-iconpicker.less"; @import "components/umb-insert-code-box.less"; @import "components/umb-packages.less"; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less new file mode 100644 index 0000000000..e9101973b4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-color-swatches.less @@ -0,0 +1,61 @@ +.umb-color-swatches { + + .umb-color-box { + border: none; + color: white; + cursor: pointer; + padding: 5px; + text-align: center; + text-decoration: none; + display: inline-block; + margin: 5px; + border-radius: 3px; + width: 30px; + height: 30px; + transition: box-shadow .3s; + + &:hover, &:focus { + box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); + } + + .check_circle { + display: none; + visibility: hidden; + width: 20px; + height: 20px; + margin: 0 auto; + + .icon { + font-size: 1em; + display: flex; + width: 100%; + height: 100%; + align-items: center; + justify-content: center; + border-radius: 50%; + background-color: rgba(0,0,0,.15); + float: left; + } + } + + &.active { + .check_circle { + display: flex; + visibility: visible; + } + } + + &.umb-color-box--s { + } + + &.umb-color-box--m { + width: 40px; + height: 40px; + + .check_circle { + width: 25px; + height: 25px; + } + } + } +} diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less index 8ed034b403..83d596b332 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-iconpicker.less @@ -40,3 +40,39 @@ .umb-iconpicker-item i { font-size: 30px; } + + +// Color swatch + .button { + border: none; + color: white; + padding: 5px; + text-align: center; + text-decoration: none; + display: inline-block; + margin: 5px; + border-radius: 3px; + } + + + .check_circle{ + width: 20px; + height: 20px; + + } + + // Hide Circle when not active + i.small{ + display: none; + } + + // Circle behind the checkmark + i.small.active{ + font-size: 14px; + display: inline-block; + width: 20px; + height: 20px; + border-radius: 50%; + background-color: rgba(0,0,0,.15); + float: right; + } diff --git a/src/Umbraco.Web.UI.Client/src/less/variables.less b/src/Umbraco.Web.UI.Client/src/less/variables.less index d72a9085ec..ddd701a13f 100644 --- a/src/Umbraco.Web.UI.Client/src/less/variables.less +++ b/src/Umbraco.Web.UI.Client/src/less/variables.less @@ -1,442 +1,509 @@ -// -// Variables -// -------------------------------------------------- - - -// Global values -// -------------------------------------------------- - - -// Grays -// ------------------------- -@black: #000; -@blackLight: #1d1d1d; -@grayDarker: #222; -@grayDark: #343434; -@gray: #555; -@grayMed: #7f7f7f; -@grayLight: #d9d9d9; -@grayLighter: #f8f8f8; -@white: #fff; - - -// Accent colors -// ------------------------- -@blue: #2e8aea; -@blueDark: #0064cd; -@blueLight: #add8e6; -@green: #46a546; -@red: #9d261d; -@yellow: #ffc40d; -@orange: #DF7F48; -@pink: #c3325f; - - -// Colors -// ------------------------- - -@turquoise-d1: #00AEA2; -@turquoise: #03BFB3; -@turquoise-l1: #42CFC5; -@turquoise-l2: #81DED8; -@turquoise-l3: #C0F0ED; -@turquoise-washed: #F3FDFC; - -@purple-d2: #1D1333; -@purple-d1: #2E2246; -@purple: #413659; -@purple-l1: #675E7A; -@purple-l2: #8D869B; -@purple-l3: #B3AFBD; -@purple-washed: #F6F3FD; - -// UI Colors -@red-d1: #F02E28; -@red: #FE3E39; -@red-l1: #FE6561; -@red-l2: #FE8B88; -@red-l3: #FFB2B0; -@red-washed: #FFECEB; - -@yellow-d2: #F0AC00; -@yellow-d1: #FFC011; -@yellow: #FFCE38; -@yellow-l1: #FFD861; -@yellow-l2: #FFE28A; -@yellow-l3: #FFECB0; -@yellow-washed: #FFFAEB; - -@green-d1: #1FB572; -@green: #35C786; -@green-l1: #4ECF95; -@green-l2: #79E1B2; -@green-l3: #A6F0CF; -@green-washed: #EBFFF6; - -// Grayscale -@gray-1: #1E1C1C; -@gray-2: #303033; -@gray-3: #515054; -@gray-4: #68676B; -@gray-5: #817F85; -@gray-6: #A2A1A6; -@gray-7: #BBBABF; -@gray-8: #D8D7D9; -@gray-9: #E9E9EB; -@gray-10: #F3F3F5; - - -.red{color: @red;} -.blue{color: @blue;} -.black{color: @black;} -.turquoise{color: @turquoise;} -.turquoise-d1{color: @turquoise-d1;} - - -//icon colors for tree icons -.color-red, .color-red i{color: @red-d1 !important;} -.color-blue, .color-blue i{color: @turquoise-d1 !important;} -.color-orange, .color-orange i{color: #d9631e !important;} -.color-green, .color-green i{color: @green-d1 !important;} -.color-yellow, .color-yellow i{color: @yellow-d1 !important;} - -/* Colors based on http://zavoloklom.github.io/material-design-color-palette/colors.html */ -.color-black, .color-black i { color: #000 !important; } -.color-blue-grey, .color-blue-grey i { color: #607d8b !important; } -.color-grey, .color-grey i { color: #9e9e9e !important; } -.color-brown, .color-brown i { color: #795548 !important; } -.color-blue, .color-blue i { color: #2196f3 !important; } -.color-light-blue, .color-light-blue i {color: #03a9f4 !important; } -.color-cyan, .color-cyan i { color: #00bcd4 !important; } -.color-green, .color-green i { color: #4caf50 !important; } -.color-light-green, .color-light-green i {color: #8bc34a !important; } -.color-lime, .color-lime i { color: #cddc39 !important; } -.color-yellow, .color-yellow i { color: #ffeb3b !important; } -.color-amber, .color-amber i { color: #ffc107 !important; } -.color-orange, .color-orange i { color: #ff9800 !important; } -.color-deep-orange, .color-deep-orange i { color: #ff5722 !important; } -.color-red, .color-red i { color: #f44336 !important; } -.color-pink, .color-pink i { color: #e91e63 !important; } -.color-purple,.color-purple i { color: #9c27b0 !important; } -.color-deep-purple, .color-deep-purple i { color: #673ab7 !important; } -.color-indigo, .color-indigo i { color: #3f51b5 !important; } - - -// Scaffolding -// ------------------------- -@bodyBackground: @white; -@textColor: @gray-2; - - -// Links -// ------------------------- -@linkColor: @black; -@linkColorHover: darken(@linkColor, 15%); - -// Typography -// ------------------------- -@sansFontFamily: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; -@serifFontFamily: Georgia, "Times New Roman", Times, serif; -@monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace; - -@baseFontSize: 15px; -@baseFontFamily: @sansFontFamily; -@baseLineHeight: 20px; -@altFontFamily: @serifFontFamily; - -@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily -@headingsFontWeight: 500; // instead of browser default, bold -@headingsColor: inherit; // empty to use BS default, @textColor - - -// Component sizing -// ------------------------- -// Based on 14px font-size and 20px line-height - -@fontSizeLarge: @baseFontSize * 1.25; // ~18px -@fontSizeMedium: @baseFontSize * 1.15; // ~14px -@fontSizeSmall: @baseFontSize * 0.85; // ~12px -@fontSizeMini: @baseFontSize * 0.75; // ~11px - -@paddingLarge: 11px 19px; // 44px -@paddingSmall: 2px 10px; // 26px -@paddingMini: 0 6px; // 22px - - -// Disabled this to keep consistency throughout the backoffice UI. Untill a better solution is thought up, this will do. -@baseBorderRadius: 3px; // 2px; -@borderRadiusLarge: 3px; // 6px; -@borderRadiusSmall: 3px; // 3px; - - -// Tables -// ------------------------- -@tableBackground: transparent; // overall background-color -@tableBackgroundAccent: @gray-10; // for striping -@tableBackgroundHover: @gray-10; // for hover -@tableBorder: @gray-8; // table and cell border - -// Buttons -// ------------------------- -@btnBackground: @gray-9; -@btnBackgroundHighlight: @gray-9; -@btnBorder: @gray-9; - -@btnPrimaryBackground: @green; -@btnPrimaryBackgroundHighlight: @green; - -@btnInfoBackground: @purple-l1; -@btnInfoBackgroundHighlight: @purple-l1; - -@btnSuccessBackground: @green; -@btnSuccessBackgroundHighlight: @green; - -@btnWarningBackground: @red-l1; -@btnWarningBackgroundHighlight: @red-l1; - -@btnDangerBackground: @red-l1; -@btnDangerBackgroundHighlight: @red-l1; - -@btnInverseBackground: @gray-2; -@btnInverseBackgroundHighlight: @gray-2; - -@btnNeutralBackground: @gray-9; -@btnNeutralBackgroundHighlight: @gray-9; - - -// Forms -// ------------------------- -@inputBackground: @white; -@inputBorder: @gray-7; -@inputBorderRadius: 0; -@inputDisabledBackground: @gray-10; -@formActionsBackground: @gray-9; -@inputHeight: @baseLineHeight + 12px; // base line-height + 8px vertical padding + 2px top/bottom border -@controlRequiredColor: @red; - - -// Tabs -// ------------------------- - -@tabsBorderRadius: @baseBorderRadius; - -// Dropdowns -// ------------------------- -@dropdownBackground: @white; -@dropdownBorder: @gray-8; -@dropdownDividerTop: @gray-8; -@dropdownDividerBottom: @white; - -@dropdownLinkColor: @gray-2; -@dropdownLinkColorHover: @white; -@dropdownLinkColorActive: @white; - -@dropdownLinkBackgroundActive: @linkColor; -@dropdownLinkBackgroundHover: @dropdownLinkBackgroundActive; - - - -// COMPONENT VARIABLES -// -------------------------------------------------- - -// Drawer -@drawerWidth: 400px; - - -// Z-index master list -// ------------------------- -// Used for a bird's eye view of components dependent on the z-axis -// Try to avoid customizing these :) -@zindexDropdown: 1000; -@zindexPopover: 1010; -@zindexTooltip: 1030; -@zindexFixedNavbar: 1030; -@zindexModalBackdrop: 1040; -@zindexModal: 1050; - -@zindexUmbOverlay: 7500; -@zindexOverlayBackdrop: 2000; - -// Sticky bar has a z-index of "500", which is set from javascript in directive -// so set z-index of cropper should be lower to be behind sticky bar. -@zindexCropperOverlay: 499; - -// Sprite icons path -// ------------------------- -@iconSpritePath: "../img/glyphicons-halflings.png"; -@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; - - -// Input placeholder text color -// ------------------------- -@placeholderText: @gray-8; - - -// Hr border color -// ------------------------- -@hrBorder: @gray-10; - - -// Horizontal forms & lists -// ------------------------- -@horizontalComponentOffset: 180px; - - -// Wells -// ------------------------- -@wellBackground: @gray-10; - - -// Navbar -// ------------------------- -@navbarCollapseWidth: 979px; -@navbarCollapseDesktopWidth: @navbarCollapseWidth + 1; - -@navbarHeight: 40px; -@navbarBackgroundHighlight: @white; -@navbarBackground: darken(@navbarBackgroundHighlight, 5%); -@navbarBorder: darken(@navbarBackground, 12%); - -@navbarText: @gray-4; -@navbarLinkColor: @gray-4; -@navbarLinkColorHover: @gray-2; -@navbarLinkColorActive: @gray-3; -@navbarLinkBackgroundHover: transparent; -@navbarLinkBackgroundActive: darken(@navbarBackground, 5%); - -@navbarBrandColor: @navbarLinkColor; - -// Inverted navbar -@navbarInverseBackground: @gray-1; -@navbarInverseBackgroundHighlight: @gray-2; -@navbarInverseBorder: @gray-2; - -@navbarInverseText: @gray-8; -@navbarInverseLinkColor: @gray-8; -@navbarInverseLinkColorHover: @white; -@navbarInverseLinkColorActive: @navbarInverseLinkColorHover; -@navbarInverseLinkBackgroundHover: transparent; -@navbarInverseLinkBackgroundActive: @navbarInverseBackground; - -@navbarInverseSearchBackground: lighten(@navbarInverseBackground, 25%); -@navbarInverseSearchBackgroundFocus: @white; -@navbarInverseSearchBorder: @navbarInverseBackground; -@navbarInverseSearchPlaceholderColor: @gray-7; - -@navbarInverseBrandColor: @navbarInverseLinkColor; - - -// Pagination -// ------------------------- -@paginationBackground: @white; -@paginationBorder: @gray-8; -@paginationActiveBackground: @gray-10; - - -// Hero unit -// ------------------------- -@heroUnitBackground: @gray-10; -@heroUnitHeadingColor: inherit; -@heroUnitLeadColor: inherit; - - -// alerts -// ------------------------- -@warningText: @white; -@warningBackground: @yellow-d2; -@warningBorder: transparent; - -@errorText: @white; -@errorBackground: @red-d1; -@errorBorder: transparent; - -@successText: @white; -@successBackground: @green-d1; -@successBorder: transparent; - -@infoText: @white; -@infoBackground: @turquoise-d1; -@infoBorder: transparent; - -@alertBorderRadius: 0; - -// SD: Had to duplicate the above but prefix with 'form' inversed colors -// because we cannot share the above alert colors with forms otherwise we end up with white -// text and giant red backgrounds. - -// Form states -// ------------------------- -@formWarningText: @warningBackground; -@formWarningBackground: lighten(@warningBackground, 38%); -@formWarningBorder: darken(spin(@warningBackground, -10), 3%); - -@formErrorText: @errorBackground; -@formErrorBackground: lighten(@errorBackground, 55%); -@formErrorBorder: darken(spin(@errorBackground, -10), 3%); - -@formSuccessText: @successBackground; -@formSuccessBackground: lighten(@successBackground, 48%); -@formSuccessBorder: darken(spin(@successBackground, -10), 5%); - -@formInfoText: @infoBackground; -@formInfoBackground: lighten(@infoBackground, 41%); -@formInfoBorder: darken(spin(@infoBackground, -10), 7%); - - -// Tooltips and popovers -// ------------------------- -@tooltipColor: @white; -@tooltipBackground: @black; -@tooltipArrowWidth: 5px; -@tooltipArrowColor: @tooltipBackground; - -@popoverBackground: @white; -@popoverArrowWidth: 10px; -@popoverArrowColor: @white; -@popoverTitleBackground: darken(@popoverBackground, 3%); - -// Special enhancement for popovers -@popoverArrowOuterWidth: @popoverArrowWidth + 1; -@popoverArrowOuterColor: @gray-7; - - - -// GRID -// -------------------------------------------------- - - -// Default 940px grid -// ------------------------- -@gridColumns: 12; -@gridColumnWidth: 60px; -@gridGutterWidth: 0px; -@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); - -// 1200px min -@gridColumnWidth1200: 70px; -@gridGutterWidth1200: 30px; -@gridRowWidth1200: (@gridColumns * @gridColumnWidth1200) + (@gridGutterWidth1200 * (@gridColumns - 1)); - -// 768px-979px -@gridColumnWidth768: 42px; -@gridGutterWidth768: 20px; -@gridRowWidth768: (@gridColumns * @gridColumnWidth768) + (@gridGutterWidth768 * (@gridColumns - 1)); - - -// Fluid grid -// ------------------------- -@fluidGridColumnWidth: percentage(@gridColumnWidth/@gridRowWidth); -@fluidGridGutterWidth: percentage(@gridGutterWidth/@gridRowWidth); - -// 1200px min -@fluidGridColumnWidth1200: percentage(@gridColumnWidth1200/@gridRowWidth1200); -@fluidGridGutterWidth1200: percentage(@gridGutterWidth1200/@gridRowWidth1200); - -// 768px-979px -@fluidGridColumnWidth768: percentage(@gridColumnWidth768/@gridRowWidth768); -@fluidGridGutterWidth768: percentage(@gridGutterWidth768/@gridRowWidth768); - -// SORTABLE -// -------------------------------------------------- -@sortableHelperBg: @turquoise-l2; -@sortablePlaceholderBg : @turquoise; +// +// Variables +// -------------------------------------------------- + + +// Global values +// -------------------------------------------------- + + +// Grays +// ------------------------- +@black: #000; +@blackLight: #1D1D1D; +@grayDarker: #222; +@grayDark: #343434; +@gray: #555; +@grayMed: #7F7F7F; +@blueGrey: #607D8B; +@grayLight: #D9D9D9; +@grayLighter: #F8F8F8; +@white: #FFF; +@grayIcon: #9E9E9E; + +// Accent colors +// ------------------------- + + + +@blue: #2E8AEA; +@blueDark: #0064CD; +@blueLight: #ADD8E6; +@green: #46A546; +@red: #9D261D; +@yellow: #FFC40D; +@orange: #DF7F48; +@pink: #C3325F; + + +// Colors +// ------------------------- + +@turquoise-d1: #00AEA2; +@turquoise: #03BFB3; +@turquoise-l1: #42CFC5; +@turquoise-l2: #81DED8; +@turquoise-l3: #C0F0ED; +@turquoise-washed: #F3FDFC; + +@purple-d2: #1D1333; +@purple-d1: #2E2246; +@purple: #413659; +@purple-l1: #675E7A; +@purple-l2: #8D869B; +@purple-l3: #B3AFBD; +@purple-washed: #F6F3FD; + +// UI Colors +@red-d1: #F02E28; +@red: #FE3E39; +@red-l1: #FE6561; +@red-l2: #FE8B88; +@red-l3: #FFB2B0; +@red-washed: #FFECEB; + +@yellow-d2: #F0AC00; +@yellow-d1: #FFC011; +@yellow: #FFCE38; +@yellow-l1: #FFD861; +@yellow-l2: #FFE28A; +@yellow-l3: #FFECB0; +@yellow-washed: #FFFAEB; + +@green-d1: #1FB572; +@green: #35C786; +@green-l1: #4ECF95; +@green-l2: #79E1B2; +@green-l3: #A6F0CF; +@green-washed: #EBFFF6; + +// Grayscale +@gray-1: #1E1C1C; +@gray-2: #303033; +@gray-3: #515054; +@gray-4: #68676B; +@gray-5: #817F85; +@gray-6: #A2A1A6; +@gray-7: #BBBABF; +@gray-8: #D8D7D9; +@gray-9: #E9E9EB; +@gray-10: #F3F3F5; + + +// Additional Icon Colours +@brownIcon: #795548; +@blueIcon: #2196F3; +@lightBlueIcon: #03A9F4; +@cyanIcon: #00BCD4; +@greenIcon: #4CAF50; +@lightGreenIcon: #8BC34A; +@limeIcon: #CDDC39; +@yellowIcon: #FFEB3B; +@amberIcon: #FFC107; +@orangeIcon: #FF9800; +@deepOrangeIcon: #FF5722; +@redIcon: #F44336; +@pinkIcon: #E91E63; +@purpleIcon: #9C27B0; +@deepPurpleIcon: #673AB7; +@indigoIcon: #3F51B5; + + + + + +.red{color: @red;} +.blue{color: @blue;} +.black{color: @black;} +.turquoise{color: @turquoise;} +.turquoise-d1{color: @turquoise-d1;} + + +//icon colors for tree icons +.color-red, .color-red i{color: @red-d1 !important;} +.color-blue, .color-blue i{color: @turquoise-d1 !important;} +.color-orange, .color-orange i{color: @orange !important;} +.color-green, .color-green i{color: @green-d1 !important;} +.color-yellow, .color-yellow i{color: @yellowIcon !important;} + +/* Colors based on http://zavoloklom.github.io/material-design-color-palette/colors.html */ +.btn-color-black {background-color: @black;} +.color-black i { color: @black;} + + +.btn-color-blue-grey {background-color: @blueGrey;} +.color-blue-grey i { color: @blueGrey; } + + +.btn-color-grey{background-color: @grayIcon;} +.color-grey i { color: @grayIcon; } + + +.btn-color-brown{background-color: @brownIcon;} +.color-brown i { color: @brownIcon; } + +.btn-color-blue{background-color: @blueIcon;} +.color-blue i { color: @blueIcon; } + +.btn-color-light-blue{background-color: @lightBlueIcon;} +.color-light-blue i {color: @lightBlueIcon;} + +.btn-color-cyan{background-color: @cyanIcon;} +.color-cyan i { color: @cyanIcon; } + +.btn-color-green{background-color: @greenIcon;} +.color-green i { color: @greenIcon } + +.btn-color-light-green{background-color: @lightGreenIcon;} +.color-light-green i {color: @lightGreenIcon; } + +.btn-color-lime{background-color: @limeIcon;} +.color-lime i { color: @limeIcon; } + +.btn-color-yellow{background-color: @yellowIcon;} +.color-yellow i { color: @yellowIcon; } + +.btn-color-amber{background-color: @amberIcon;} +.color-amber i { color: @amberIcon; } + +.btn-color-orange{background-color: @orangeIcon;} +.color-orange i { color: @orangeIcon; } + +.btn-color-deep-orange{background-color: @deepOrangeIcon;} +.color-deep-orange i { color: @deepOrangeIcon; } + +.btn-color-red{background-color: @redIcon;} +.color-red i { color: @redIcon; } + +.btn-color-pink{background-color: @pinkIcon;} +.color-pink i { color: @pinkIcon; } + +.btn-color-purple{background-color: @purpleIcon;} +.color-purple i { color: @purpleIcon; } + +.btn-color-deep-purple{background-color: @deepPurpleIcon;} +.color-deep-purple i { color: @deepPurpleIcon; } + +.btn-color-indigo{background-color: @indigoIcon;} +.color-indigo i { color: @indigoIcon; } + + + +// Scaffolding +// ------------------------- +@bodyBackground: @white; +@textColor: @gray-2; + + +// Links +// ------------------------- +@linkColor: @black; +@linkColorHover: darken(@linkColor, 15%); + +// Typography +// ------------------------- +@sansFontFamily: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif; +@serifFontFamily: Georgia, "Times New Roman", Times, serif; +@monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace; + +@baseFontSize: 15px; +@baseFontFamily: @sansFontFamily; +@baseLineHeight: 20px; +@altFontFamily: @serifFontFamily; + +@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily +@headingsFontWeight: 500; // instead of browser default, bold +@headingsColor: inherit; // empty to use BS default, @textColor + + +// Component sizing +// ------------------------- +// Based on 14px font-size and 20px line-height + +@fontSizeLarge: @baseFontSize * 1.25; // ~18px +@fontSizeMedium: @baseFontSize * 1.15; // ~14px +@fontSizeSmall: @baseFontSize * 0.85; // ~12px +@fontSizeMini: @baseFontSize * 0.75; // ~11px + +@paddingLarge: 11px 19px; // 44px +@paddingSmall: 2px 10px; // 26px +@paddingMini: 0 6px; // 22px + + +// Disabled this to keep consistency throughout the backoffice UI. Untill a better solution is thought up, this will do. +@baseBorderRadius: 3px; // 2px; +@borderRadiusLarge: 3px; // 6px; +@borderRadiusSmall: 3px; // 3px; + + +// Tables +// ------------------------- +@tableBackground: transparent; // overall background-color +@tableBackgroundAccent: @gray-10; // for striping +@tableBackgroundHover: @gray-10; // for hover +@tableBorder: @gray-8; // table and cell border + +// Buttons +// ------------------------- +@btnBackground: @gray-9; +@btnBackgroundHighlight: @gray-9; +@btnBorder: @gray-9; + +@btnPrimaryBackground: @green; +@btnPrimaryBackgroundHighlight: @green; + +@btnInfoBackground: @purple-l1; +@btnInfoBackgroundHighlight: @purple-l1; + +@btnSuccessBackground: @green; +@btnSuccessBackgroundHighlight: @green; + +@btnWarningBackground: @red-l1; +@btnWarningBackgroundHighlight: @red-l1; + +@btnDangerBackground: @red-l1; +@btnDangerBackgroundHighlight: @red-l1; + +@btnInverseBackground: @gray-2; +@btnInverseBackgroundHighlight: @gray-2; + +@btnNeutralBackground: @gray-9; +@btnNeutralBackgroundHighlight: @gray-9; + + +// Forms +// ------------------------- +@inputBackground: @white; +@inputBorder: @gray-7; +@inputBorderRadius: 0; +@inputDisabledBackground: @gray-10; +@formActionsBackground: @gray-9; +@inputHeight: @baseLineHeight + 12px; // base line-height + 8px vertical padding + 2px top/bottom border +@controlRequiredColor: @red; + + +// Tabs +// ------------------------- + +@tabsBorderRadius: @baseBorderRadius; + +// Dropdowns +// ------------------------- +@dropdownBackground: @white; +@dropdownBorder: @gray-8; +@dropdownDividerTop: @gray-8; +@dropdownDividerBottom: @white; + +@dropdownLinkColor: @gray-2; +@dropdownLinkColorHover: @white; +@dropdownLinkColorActive: @white; + +@dropdownLinkBackgroundActive: @linkColor; +@dropdownLinkBackgroundHover: @dropdownLinkBackgroundActive; + + + +// COMPONENT VARIABLES +// -------------------------------------------------- + +// Drawer +@drawerWidth: 400px; + + +// Z-index master list +// ------------------------- +// Used for a bird's eye view of components dependent on the z-axis +// Try to avoid customizing these :) +@zindexDropdown: 1000; +@zindexPopover: 1010; +@zindexTooltip: 1030; +@zindexFixedNavbar: 1030; +@zindexModalBackdrop: 1040; +@zindexModal: 1050; + +@zindexUmbOverlay: 7500; +@zindexOverlayBackdrop: 2000; + +// Sticky bar has a z-index of "500", which is set from javascript in directive +// so set z-index of cropper should be lower to be behind sticky bar. +@zindexCropperOverlay: 499; + +// Sprite icons path +// ------------------------- +@iconSpritePath: "../img/glyphicons-halflings.png"; +@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; + + +// Input placeholder text color +// ------------------------- +@placeholderText: @gray-8; + + +// Hr border color +// ------------------------- +@hrBorder: @gray-10; + + +// Horizontal forms & lists +// ------------------------- +@horizontalComponentOffset: 180px; + + +// Wells +// ------------------------- +@wellBackground: @gray-10; + + +// Navbar +// ------------------------- +@navbarCollapseWidth: 979px; +@navbarCollapseDesktopWidth: @navbarCollapseWidth + 1; + +@navbarHeight: 40px; +@navbarBackgroundHighlight: @white; +@navbarBackground: darken(@navbarBackgroundHighlight, 5%); +@navbarBorder: darken(@navbarBackground, 12%); + +@navbarText: @gray-4; +@navbarLinkColor: @gray-4; +@navbarLinkColorHover: @gray-2; +@navbarLinkColorActive: @gray-3; +@navbarLinkBackgroundHover: transparent; +@navbarLinkBackgroundActive: darken(@navbarBackground, 5%); + +@navbarBrandColor: @navbarLinkColor; + +// Inverted navbar +@navbarInverseBackground: @gray-1; +@navbarInverseBackgroundHighlight: @gray-2; +@navbarInverseBorder: @gray-2; + +@navbarInverseText: @gray-8; +@navbarInverseLinkColor: @gray-8; +@navbarInverseLinkColorHover: @white; +@navbarInverseLinkColorActive: @navbarInverseLinkColorHover; +@navbarInverseLinkBackgroundHover: transparent; +@navbarInverseLinkBackgroundActive: @navbarInverseBackground; + +@navbarInverseSearchBackground: lighten(@navbarInverseBackground, 25%); +@navbarInverseSearchBackgroundFocus: @white; +@navbarInverseSearchBorder: @navbarInverseBackground; +@navbarInverseSearchPlaceholderColor: @gray-7; + +@navbarInverseBrandColor: @navbarInverseLinkColor; + + +// Pagination +// ------------------------- +@paginationBackground: @white; +@paginationBorder: @gray-8; +@paginationActiveBackground: @gray-10; + + +// Hero unit +// ------------------------- +@heroUnitBackground: @gray-10; +@heroUnitHeadingColor: inherit; +@heroUnitLeadColor: inherit; + + +// alerts +// ------------------------- +@warningText: @white; +@warningBackground: @yellow-d2; +@warningBorder: transparent; + +@errorText: @white; +@errorBackground: @red-d1; +@errorBorder: transparent; + +@successText: @white; +@successBackground: @green-d1; +@successBorder: transparent; + +@infoText: @white; +@infoBackground: @turquoise-d1; +@infoBorder: transparent; + +@alertBorderRadius: 0; + +// SD: Had to duplicate the above but prefix with 'form' inversed colors +// because we cannot share the above alert colors with forms otherwise we end up with white +// text and giant red backgrounds. + +// Form states +// ------------------------- +@formWarningText: @warningBackground; +@formWarningBackground: lighten(@warningBackground, 38%); +@formWarningBorder: darken(spin(@warningBackground, -10), 3%); + +@formErrorText: @errorBackground; +@formErrorBackground: lighten(@errorBackground, 55%); +@formErrorBorder: darken(spin(@errorBackground, -10), 3%); + +@formSuccessText: @successBackground; +@formSuccessBackground: lighten(@successBackground, 48%); +@formSuccessBorder: darken(spin(@successBackground, -10), 5%); + +@formInfoText: @infoBackground; +@formInfoBackground: lighten(@infoBackground, 41%); +@formInfoBorder: darken(spin(@infoBackground, -10), 7%); + + +// Tooltips and popovers +// ------------------------- +@tooltipColor: @white; +@tooltipBackground: @black; +@tooltipArrowWidth: 5px; +@tooltipArrowColor: @tooltipBackground; + +@popoverBackground: @white; +@popoverArrowWidth: 10px; +@popoverArrowColor: @white; +@popoverTitleBackground: darken(@popoverBackground, 3%); + +// Special enhancement for popovers +@popoverArrowOuterWidth: @popoverArrowWidth + 1; +@popoverArrowOuterColor: @gray-7; + + + +// GRID +// -------------------------------------------------- + + +// Default 940px grid +// ------------------------- +@gridColumns: 12; +@gridColumnWidth: 60px; +@gridGutterWidth: 0px; +@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); + +// 1200px min +@gridColumnWidth1200: 70px; +@gridGutterWidth1200: 30px; +@gridRowWidth1200: (@gridColumns * @gridColumnWidth1200) + (@gridGutterWidth1200 * (@gridColumns - 1)); + +// 768px-979px +@gridColumnWidth768: 42px; +@gridGutterWidth768: 20px; +@gridRowWidth768: (@gridColumns * @gridColumnWidth768) + (@gridGutterWidth768 * (@gridColumns - 1)); + + +// Fluid grid +// ------------------------- +@fluidGridColumnWidth: percentage(@gridColumnWidth/@gridRowWidth); +@fluidGridGutterWidth: percentage(@gridGutterWidth/@gridRowWidth); + +// 1200px min +@fluidGridColumnWidth1200: percentage(@gridColumnWidth1200/@gridRowWidth1200); +@fluidGridGutterWidth1200: percentage(@gridGutterWidth1200/@gridRowWidth1200); + +// 768px-979px +@fluidGridColumnWidth768: percentage(@gridColumnWidth768/@gridRowWidth768); +@fluidGridGutterWidth768: percentage(@gridGutterWidth768/@gridRowWidth768); + +// SORTABLE +// -------------------------------------------------- +@sortableHelperBg: @turquoise-l2; +@sortablePlaceholderBg : @turquoise; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.controller.js index 7a186f3d6b..3c36505fcb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.controller.js @@ -8,8 +8,35 @@ */ function IconPickerOverlay($scope, iconHelper, localizationService) { - $scope.loading = true; - $scope.model.hideSubmitButton = false; + $scope.loading = true; + $scope.model.hideSubmitButton = false; + + $scope.colors = [ + { name: "Black", value: "color-black" }, + { name: "Blue Grey", value: "color-blue-grey" }, + { name: "Grey", value: "color-grey" }, + { name: "Brown", value: "color-brown" }, + { name: "Blue", value: "color-blue" }, + { name: "Light Blue", value: "color-light-blue" }, + { name: "Indigo", value: "color-indigo" }, + { name: "Purple", value: "color-purple" }, + { name: "Deep Purple", value: "color-deep-purple" }, + { name: "Cyan", value: "color-cyan" }, + { name: "Green", value: "color-green" }, + { name: "Light Green", value: "color-light-green" }, + { name: "Lime", value: "color-lime" }, + { name: "Yellow", value: "color-yellow" }, + { name: "Amber", value: "color-amber" }, + { name: "Orange", value: "color-orange" }, + { name: "Deep Orange", value: "color-deep-orange" }, + { name: "Red", value: "color-red" }, + { name: "Pink", value: "color-pink" } + ]; + + if (!$scope.color) { + // Set default selected color to black + $scope.color = $scope.colors[0].value; + }; if (!$scope.model.title) { $scope.model.title = localizationService.localize("defaultdialogs_selectIcon"); @@ -23,20 +50,29 @@ function IconPickerOverlay($scope, iconHelper, localizationService) { $scope.icon = $scope.model.icon; }; - iconHelper.getIcons().then(function(icons) { - $scope.icons = icons; - $scope.loading = false; - }); + iconHelper.getIcons().then(function (icons) { + $scope.icons = icons; + $scope.loading = false; + }); - $scope.selectIcon = function(icon, color) { - $scope.model.icon = icon; - $scope.model.color = color; - $scope.submitForm($scope.model); - }; - - $scope.changeColor = function (color) { + $scope.selectIcon = function (icon, color) { + $scope.model.icon = icon; $scope.model.color = color; + $scope.submitForm($scope.model); }; + + var unsubscribe = $scope.$on("formSubmitting", + function () { + if ($scope.color) { + $scope.model.color = $scope.color; + } + }); + + //when the scope is destroyed we need to unsubscribe + $scope.$on("$destroy", + function () { + unsubscribe(); + }); } angular.module("umbraco").controller("Umbraco.Overlays.IconPickerOverlay", IconPickerOverlay); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.html index 78a215d009..0098463cb4 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/iconpicker/iconpicker.html @@ -1,3 +1,5 @@ + +
@@ -15,27 +17,7 @@
- +
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html new file mode 100644 index 0000000000..eae299e579 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-color-swatches.html @@ -0,0 +1,9 @@ +
+ + + +
From 8a3232bd2363d2af2ba16826660800619f4d5320 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 26 Jul 2018 10:39:13 +0200 Subject: [PATCH 064/134] Renormalize --- src/Umbraco.Web/Umbraco.Web.csproj | 3166 ++++++++++++++-------------- 1 file changed, 1583 insertions(+), 1583 deletions(-) diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 4d61686c61..5b32d4e76f 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1,1584 +1,1584 @@ - - - - - v4.7.2 - false - false - {651E1350-91B6-44B7-BD60-7207006D7003} - Library - Umbraco.Web - Umbraco.Web - ..\ - true - Off - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - latest - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - bin\Release\Umbraco.Web.xml - false - latest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {31785bc3-256c-4613-b2f5-a1b0bdded8c1} - Umbraco.Core - - - Umbraco.Examine - {07FBC26B-2927-4A22-8D96-D644C667FECC} - - - - - - - Properties\SolutionInfo.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ASPXCodeBehind - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ASPXCodeBehind - - - - - True - True - Reference.map - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - True - Resources.resx - - - - - - - - - - - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - AssignDomain2.aspx - ASPXCodeBehind - - - AssignDomain2.aspx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ASPXCodeBehind - - - - - - - - - - - - - - - - - - - - - True - True - Strings.resx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ASPXCodeBehind - - - ASPXCodeBehind - - - - ASPXCodeBehind - - - - - ASPXCodeBehind - - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code - - - Code - - - Code - - - Code - - - True - True - Settings.settings - - - Code - - - - - ASPXCodeBehind - - - Component - - - - - Code - - - - - - - FeedProxy.aspx - ASPXCodeBehind - - - FeedProxy.aspx - - - EditRelationType.aspx - - - EditRelationType.aspx - - - NewRelationType.aspx - ASPXCodeBehind - - - NewRelationType.aspx - - - RelationTypesWebService.asmx - Component - - - - - Preview.aspx - ASPXCodeBehind - - - Preview.aspx - - - insertMasterpageContent.aspx - ASPXCodeBehind - - - insertMasterpageContent.aspx - - - insertMasterpagePlaceholder.aspx - ASPXCodeBehind - - - insertMasterpagePlaceholder.aspx - - - republish.aspx - - - republish.aspx - - - SendPublish.aspx - ASPXCodeBehind - - - SendPublish.aspx - - - Code - - - editPackage.aspx - ASPXCodeBehind - - - editPackage.aspx - - - exportDocumenttype.aspx - ASPXCodeBehind - - - importDocumenttype.aspx - ASPXCodeBehind - - - notifications.aspx - ASPXCodeBehind - - - notifications.aspx - - - rollBack.aspx - - - rollBack.aspx - - - sendToTranslation.aspx - ASPXCodeBehind - - - sendToTranslation.aspx - - - viewAuditTrail.aspx - ASPXCodeBehind - - - viewAuditTrail.aspx - - - DictionaryItemList.aspx - ASPXCodeBehind - - - DictionaryItemList.aspx - - - EditDictionaryItem.aspx - ASPXCodeBehind - - - EditDictionaryItem.aspx - - - Code - - - - - - - - - - - default.aspx - ASPXCodeBehind - - - default.aspx - - - details.aspx - ASPXCodeBehind - - - details.aspx - - - preview.aspx - ASPXCodeBehind - - - preview.aspx - - - xml.aspx - ASPXCodeBehind - - - xml.aspx - - - - - - - - - - - - CheckForUpgrade.asmx - Component - - - legacyAjaxCalls.asmx - Component - - - nodeSorter.asmx - Component - - - ASPXCodeBehind - - - - - - - True - True - Reference.map - - - - - Component - - - - Component - - - - - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - ResXFileCodeGenerator - Strings.Designer.cs - - - - - - - - - - - - ASPXCodeBehind - - - ASPXCodeBehind - - - - - ASPXCodeBehind - - - - - - - - ASPXCodeBehind - - - ASPXCodeBehind - - - - - ASPXCodeBehind - - - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - - - ASPXCodeBehind - - - - - ASPXCodeBehind - - - ASPXCodeBehind - - - - ASPXCodeBehind - - - - - - - MSDiscoCodeGenerator - Reference.cs - Designer - - - Mvc\web.config - - - MSDiscoCodeGenerator - Reference.cs - - - - - Reference.map - - - Reference.map - - - SettingsSingleFileGenerator - Settings1.Designer.cs - - - - - Dynamic - Web References\org.umbraco.our\ - http://our.umbraco.org/umbraco/webservices/api/repository.asmx - - - - - Settings - umbraco_org_umbraco_our_Repository - - - Dynamic - Web References\org.umbraco.update\ - http://update.umbraco.org/checkforupgrade.asmx - - - - - Settings - umbraco_org_umbraco_update_CheckForUpgrade - - - - - - - $(PlatformTargetAsMSBuildArchitecture) - - - - - - - - - - - + + + + + v4.7.2 + false + false + {651E1350-91B6-44B7-BD60-7207006D7003} + Library + Umbraco.Web + Umbraco.Web + ..\ + true + Off + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + latest + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\Umbraco.Web.xml + false + latest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {31785bc3-256c-4613-b2f5-a1b0bdded8c1} + Umbraco.Core + + + Umbraco.Examine + {07FBC26B-2927-4A22-8D96-D644C667FECC} + + + + + + + Properties\SolutionInfo.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ASPXCodeBehind + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ASPXCodeBehind + + + + + True + True + Reference.map + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + + + + + ASPXCodeBehind + + + ASPXCodeBehind + + + ASPXCodeBehind + + + ASPXCodeBehind + + + AssignDomain2.aspx + ASPXCodeBehind + + + AssignDomain2.aspx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ASPXCodeBehind + + + + + + + + + + + + + + + + + + + + + True + True + Strings.resx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ASPXCodeBehind + + + ASPXCodeBehind + + + + ASPXCodeBehind + + + + + ASPXCodeBehind + + + + ASPXCodeBehind + + + ASPXCodeBehind + + + ASPXCodeBehind + + + ASPXCodeBehind + + + ASPXCodeBehind + + + ASPXCodeBehind + + + ASPXCodeBehind + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + Code + + + Code + + + Code + + + True + True + Settings.settings + + + Code + + + + + ASPXCodeBehind + + + Component + + + + + Code + + + + + + + FeedProxy.aspx + ASPXCodeBehind + + + FeedProxy.aspx + + + EditRelationType.aspx + + + EditRelationType.aspx + + + NewRelationType.aspx + ASPXCodeBehind + + + NewRelationType.aspx + + + RelationTypesWebService.asmx + Component + + + + + Preview.aspx + ASPXCodeBehind + + + Preview.aspx + + + insertMasterpageContent.aspx + ASPXCodeBehind + + + insertMasterpageContent.aspx + + + insertMasterpagePlaceholder.aspx + ASPXCodeBehind + + + insertMasterpagePlaceholder.aspx + + + republish.aspx + + + republish.aspx + + + SendPublish.aspx + ASPXCodeBehind + + + SendPublish.aspx + + + Code + + + editPackage.aspx + ASPXCodeBehind + + + editPackage.aspx + + + exportDocumenttype.aspx + ASPXCodeBehind + + + importDocumenttype.aspx + ASPXCodeBehind + + + notifications.aspx + ASPXCodeBehind + + + notifications.aspx + + + rollBack.aspx + + + rollBack.aspx + + + sendToTranslation.aspx + ASPXCodeBehind + + + sendToTranslation.aspx + + + viewAuditTrail.aspx + ASPXCodeBehind + + + viewAuditTrail.aspx + + + DictionaryItemList.aspx + ASPXCodeBehind + + + DictionaryItemList.aspx + + + EditDictionaryItem.aspx + ASPXCodeBehind + + + EditDictionaryItem.aspx + + + Code + + + + + + + + + + + default.aspx + ASPXCodeBehind + + + default.aspx + + + details.aspx + ASPXCodeBehind + + + details.aspx + + + preview.aspx + ASPXCodeBehind + + + preview.aspx + + + xml.aspx + ASPXCodeBehind + + + xml.aspx + + + + + + + + + + + + CheckForUpgrade.asmx + Component + + + legacyAjaxCalls.asmx + Component + + + nodeSorter.asmx + Component + + + ASPXCodeBehind + + + + + + + True + True + Reference.map + + + + + Component + + + + Component + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + ResXFileCodeGenerator + Strings.Designer.cs + + + + + + + + + + + + ASPXCodeBehind + + + ASPXCodeBehind + + + + + ASPXCodeBehind + + + + + + + + ASPXCodeBehind + + + ASPXCodeBehind + + + + + ASPXCodeBehind + + + + + ASPXCodeBehind + + + ASPXCodeBehind + + + ASPXCodeBehind + + + + + ASPXCodeBehind + + + + + ASPXCodeBehind + + + ASPXCodeBehind + + + + ASPXCodeBehind + + + + + + + MSDiscoCodeGenerator + Reference.cs + Designer + + + Mvc\web.config + + + MSDiscoCodeGenerator + Reference.cs + + + + + Reference.map + + + Reference.map + + + SettingsSingleFileGenerator + Settings1.Designer.cs + + + + + Dynamic + Web References\org.umbraco.our\ + http://our.umbraco.org/umbraco/webservices/api/repository.asmx + + + + + Settings + umbraco_org_umbraco_our_Repository + + + Dynamic + Web References\org.umbraco.update\ + http://update.umbraco.org/checkforupgrade.asmx + + + + + Settings + umbraco_org_umbraco_update_CheckForUpgrade + + + + + + + $(PlatformTargetAsMSBuildArchitecture) + + + + + + + + + + + \ No newline at end of file From 0f3a8bff5d9ed6422113e1c4be8de9522c6fa281 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Thu, 26 Jul 2018 11:17:53 +0200 Subject: [PATCH 065/134] Add consistency and a few localizations --- .../src/less/property-editors.less | 77 ++++++++++--------- .../views/prevalueeditors/multivalues.html | 4 +- .../colorpicker/colorpicker.prevalues.html | 28 ++++--- .../multicolorpicker.controller.js | 2 +- 4 files changed, 62 insertions(+), 49 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index c70688d935..6a576c0e5e 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -148,47 +148,52 @@ ul.color-picker li a { cursor:pointer; } -.control-group.color-picker-preval .thumbnail { - width: 30px; - border: none; - cursor: move; -} + /* pre-value editor */ -.control-group.color-picker-preval .handle { - float: left; - display: inline-block; - margin: 5px 3px 5px 0; -} -.control-group.color-picker-preval div.color-picker-prediv { - display: inline-block; - width: 50%; -} +.control-group.color-picker-preval { + .thumbnail { + width: 30px; + border: none; + cursor: move; + } -.control-group.color-picker-preval pre { - display: inline; - font-family: monospace; - margin-right: 10px; - margin-left: 10px; - width: 50%; - white-space: nowrap; - overflow: hidden; - margin-bottom: 0; - vertical-align: middle; - padding-top: 7px; - padding-bottom: 7px; -} + .handle { + float: left; + display: inline-flex; + margin: 5px 3px 5px 0; + } -.control-group.color-picker-preval input[type="text"] { - min-width: 40%; - width: 40%; - display: inline-block; - margin-top: 1px; -} + div.color-picker-prediv { + display: inline-flex; + align-items: center; + } -.control-group.color-picker-preval label { - border: 1px solid @white; - padding: 6px; + pre { + display: inline; + font-family: monospace; + margin-right: 10px; + margin-left: 10px; + width: 50%; + white-space: nowrap; + overflow: hidden; + margin-bottom: 0; + vertical-align: middle; + padding-top: 7px; + padding-bottom: 7px; + } + + input[type="text"] { + min-width: 40%; + width: 40%; + display: inline-block; + margin-top: 1px; + } + + label { + border: 1px solid @white; + padding: 6px; + } } diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/multivalues.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/multivalues.html index 5c7d3b52c2..f9fbf0b9f0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/multivalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/multivalues.html @@ -4,7 +4,7 @@
- +
@@ -14,7 +14,7 @@
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html index 1df2e87685..3d9e2efdf8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.prevalues.html @@ -1,16 +1,24 @@ -
-
- - - - +
+
+
+ + + +
+
+ +
-
+
-
-
#{{item.value}}
{{item.label}}
- +
+
+
#{{item.value}}
{{item.label}}
+
+
+ Remove +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js index 3819b054a3..7ae728a85a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/multicolorpicker.controller.js @@ -131,7 +131,7 @@ axis: 'y', containment: 'parent', cursor: 'move', - handle: ".handle, .thumbnail", + //handle: ".handle, .thumbnail", items: '> div.control-group', tolerance: 'pointer', update: function (e, ui) { From 8c88f8709b85da44eab1f7a578f602afab877c57 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 26 Jul 2018 11:22:53 +0200 Subject: [PATCH 066/134] Fix merge --- src/Umbraco.Web/Umbraco.Web.csproj | 38 +----------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 53da8e673d..581c0ae815 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -58,7 +58,6 @@ - @@ -295,8 +294,6 @@ - - @@ -462,8 +459,6 @@ - - @@ -508,7 +503,6 @@ - @@ -772,7 +766,6 @@ - @@ -1068,8 +1061,6 @@ - - @@ -1214,9 +1205,6 @@ Code - - Code - Code @@ -1305,9 +1293,6 @@ SendPublish.aspx - - Code - editPackage.aspx ASPXCodeBehind @@ -1315,10 +1300,6 @@ editPackage.aspx - - exportDocumenttype.aspx - ASPXCodeBehind - importDocumenttype.aspx ASPXCodeBehind @@ -1446,22 +1427,6 @@ Component - - - - - - - - - - Component - - - - Component - - @@ -1526,7 +1491,6 @@ ASPXCodeBehind - ASPXCodeBehind @@ -1616,4 +1580,4 @@ - \ No newline at end of file + From 1f353da33cb026efe2b31452b18213c08f5a5e13 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 26 Jul 2018 11:23:06 +0200 Subject: [PATCH 067/134] Cleanup IShortStringHelper if controller is gone --- .../Strings/DefaultShortStringHelper.cs | 51 ------------------- .../Strings/IShortStringHelper.cs | 5 -- .../Strings/MockShortStringHelper.cs | 2 - 3 files changed, 58 deletions(-) diff --git a/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs b/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs index 2e2ec8094a..84ab0de585 100644 --- a/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs +++ b/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs @@ -61,57 +61,6 @@ namespace Umbraco.Core.Strings #endregion - #region JavaScript - - private const string SssjsFormat = @" -var UMBRACO_FORCE_SAFE_ALIAS = {0}; -var UMBRACO_FORCE_SAFE_ALIAS_URL = '{1}'; -var UMBRACO_FORCE_SAFE_ALIAS_TIMEOUT = 666; -var UMBRACO_FORCE_SAFE_ALIAS_TMKEY = 'safe-alias-tmout'; - -function getSafeAliasFromServer(value, callback) {{ - $.getJSON(UMBRACO_FORCE_SAFE_ALIAS_URL + 'ToSafeAlias?value=' + encodeURIComponent(value), function(json) {{ - if (json.alias) {{ callback(json.alias); }} - }}); -}} - -function getSafeAlias(input, value, immediate, callback) {{ - if (!UMBRACO_FORCE_SAFE_ALIAS) {{ - callback(value); - return; - }} - var timeout = input.data(UMBRACO_FORCE_SAFE_ALIAS_TMKEY); - if (timeout) clearTimeout(timeout); - input.data(UMBRACO_FORCE_SAFE_ALIAS_TMKEY, setTimeout(function() {{ - input.removeData(UMBRACO_FORCE_SAFE_ALIAS_TMKEY); - getSafeAliasFromServer(value, function(alias) {{ callback(alias); }}); - }}, UMBRACO_FORCE_SAFE_ALIAS_TIMEOUT)); -}} - -function validateSafeAlias(input, value, immediate, callback) {{ - if (!UMBRACO_FORCE_SAFE_ALIAS) {{ - callback(true); - return; - }} - var timeout = input.data(UMBRACO_FORCE_SAFE_ALIAS_TMKEY); - if (timeout) clearTimeout(timeout); - input.data(UMBRACO_FORCE_SAFE_ALIAS_TMKEY, setTimeout(function() {{ - input.removeData(UMBRACO_FORCE_SAFE_ALIAS_TMKEY); - getSafeAliasFromServer(value, function(alias) {{ callback(value.toLowerCase() == alias.toLowerCase()); }}); - }}, UMBRACO_FORCE_SAFE_ALIAS_TIMEOUT)); -}} -"; - - /// - /// Gets the JavaScript code defining client-side short string services. - /// - public string GetShortStringServicesJavaScript(string controllerPath) - { - return string.Format(SssjsFormat, _config.ForceSafeAliases ? "true" : "false", controllerPath); - } - - #endregion - #region IShortStringHelper CleanFor... /// diff --git a/src/Umbraco.Core/Strings/IShortStringHelper.cs b/src/Umbraco.Core/Strings/IShortStringHelper.cs index fe5ebe0bf8..085b5adb7a 100644 --- a/src/Umbraco.Core/Strings/IShortStringHelper.cs +++ b/src/Umbraco.Core/Strings/IShortStringHelper.cs @@ -6,11 +6,6 @@ /// Not necessarily optimized to work on large bodies of text. public interface IShortStringHelper { - /// - /// Gets the JavaScript code defining client-side short string services. - /// - string GetShortStringServicesJavaScript(string controllerPath); - /// /// Cleans a string to produce a string that can safely be used in an alias. /// diff --git a/src/Umbraco.Tests/Strings/MockShortStringHelper.cs b/src/Umbraco.Tests/Strings/MockShortStringHelper.cs index e0df7ea4e9..a39f962908 100644 --- a/src/Umbraco.Tests/Strings/MockShortStringHelper.cs +++ b/src/Umbraco.Tests/Strings/MockShortStringHelper.cs @@ -12,8 +12,6 @@ namespace Umbraco.Tests.Strings public bool IsFrozen { get; private set; } - public string GetShortStringServicesJavaScript(string controllerPath) { return "SSSJS"; } - public string CleanStringForSafeAlias(string text) { return "SAFE-ALIAS::" + text; From 99181d5bf45add5400dbc33ea57caf293fb38ec6 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Thu, 26 Jul 2018 11:23:24 +0200 Subject: [PATCH 068/134] Adjust thumbnail styling --- src/Umbraco.Web.UI.Client/src/less/property-editors.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 6a576c0e5e..afc14f0520 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -153,9 +153,10 @@ ul.color-picker li a { /* pre-value editor */ .control-group.color-picker-preval { .thumbnail { - width: 30px; + width: 36px; border: none; cursor: move; + border-radius: 3px; } .handle { From d2e8b084f523b4d93f373fa31d4a26fd11fc1aa2 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Thu, 26 Jul 2018 11:25:38 +0200 Subject: [PATCH 069/134] Remove width on label --- src/Umbraco.Web.UI.Client/src/less/property-editors.less | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index afc14f0520..d247e9eb3b 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -186,7 +186,6 @@ ul.color-picker li a { input[type="text"] { min-width: 40%; - width: 40%; display: inline-block; margin-top: 1px; } From 89c84c7a309163f717bb7972927514ab94ea1e9a Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Thu, 26 Jul 2018 11:28:24 +0200 Subject: [PATCH 070/134] Set same width as for multivalues --- src/Umbraco.Web.UI.Client/src/less/property-editors.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index d247e9eb3b..798d8d0059 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -186,6 +186,7 @@ ul.color-picker li a { input[type="text"] { min-width: 40%; + width: 320px; display: inline-block; margin-top: 1px; } From c571284f403d50e8466d3bf8c950892ed58064b0 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Thu, 26 Jul 2018 11:50:31 +0200 Subject: [PATCH 071/134] Adjust a bit more styling --- .../src/less/property-editors.less | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 798d8d0059..7075cd15f9 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -168,20 +168,25 @@ ul.color-picker li a { div.color-picker-prediv { display: inline-flex; align-items: center; - } - pre { - display: inline; - font-family: monospace; - margin-right: 10px; - margin-left: 10px; - width: 50%; - white-space: nowrap; - overflow: hidden; - margin-bottom: 0; - vertical-align: middle; - padding-top: 7px; - padding-bottom: 7px; + pre { + display: inline; + font-family: monospace; + margin-right: 10px; + margin-left: 10px; + width: 50%; + white-space: nowrap; + overflow: hidden; + margin-bottom: 0; + vertical-align: middle; + padding-top: 7px; + padding-bottom: 7px; + background: #f7f7f7; + } + + span { + margin-left: 5px; + } } input[type="text"] { @@ -191,9 +196,18 @@ ul.color-picker li a { margin-top: 1px; } + .sp-replacer { + margin-right: 18px; + } + label { - border: 1px solid @white; - padding: 6px; + border: 1px solid #fff; + padding: 7px 10px; + font-family: monospace; + border: 1px solid #dfdfe1; + background: #f7f7f7; + margin: 0 15px 0 0; + border-radius: 3px; } } From 567863079ecf4e14e3891bd1240223b071471137 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Thu, 26 Jul 2018 12:03:31 +0200 Subject: [PATCH 072/134] Update a few names and descriptions for prevalues --- .../PropertyEditors/ColorListPreValueEditor.cs | 4 ++-- .../PropertyEditors/ValueListPreValueEditor.cs | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs index 20dd3f9ec8..4eb9d04217 100644 --- a/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ColorListPreValueEditor.cs @@ -22,9 +22,9 @@ namespace Umbraco.Web.PropertyEditors //use a custom editor too field.View = "views/propertyeditors/colorpicker/colorpicker.prevalues.html"; //change the description - field.Description = "Add and remove colors"; + field.Description = "Add, remove or sort colors."; //change the label - field.Name = "Add color"; + field.Name = "Colors"; //need to have some custom validation happening here field.Validators.Add(new ColorListValidator()); diff --git a/src/Umbraco.Web/PropertyEditors/ValueListPreValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ValueListPreValueEditor.cs index 42484282e9..99400b4b48 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueListPreValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueListPreValueEditor.cs @@ -2,14 +2,12 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; -using System.Text.RegularExpressions; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; -using umbraco; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { @@ -37,7 +35,7 @@ namespace Umbraco.Web.PropertyEditors { new PreValueField(new EnsureUniqueValuesValidator()) { - Description = "Add and remove values for the list", + Description = "Add, remove or sort values for the list.", //we're going to call this 'items' because we are going to override the //serialization of the pre-values to ensure that each one gets saved with it's own key //(new db row per pre-value, thus to maintain backwards compatibility) @@ -45,7 +43,7 @@ namespace Umbraco.Web.PropertyEditors //It's also important to note that by default the dropdown angular controller is expecting the // config options to come in with a property called 'items' Key = "items", - Name = ui.Text("editdatatype", "addPrevalue"), + Name = ApplicationContext.Current.Services.TextService.Localize("editdatatype/addPrevalue"), View = "multivalues" } }; From 26a49fbe9feb2d27736f9f88a860c626fb1f3df9 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 26 Jul 2018 15:55:33 +0200 Subject: [PATCH 073/134] Fixes U4-9244 --- .../src/less/components/umb-grid.less | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-grid.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-grid.less index 107c14ad86..49f0892bb0 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-grid.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-grid.less @@ -537,15 +537,11 @@ .umb-grid textarea.textstring { display: block; overflow: hidden; - border: none; background: @white; outline: none; resize: none; color: @gray-3; -} - -.umb-grid .umb-cell-rte textarea.mceNoEditor { - display: none !important; + min-width: 100%; } .umb-grid .umb-cell-media .caption { @@ -567,11 +563,6 @@ width: 100%; } -.umb-grid .umb-cell-rte { - border-color: transparent; -} - - // ICONS // ------------------------- From 7109338f683ca1f8f7470deb7346ceb504dd72bb Mon Sep 17 00:00:00 2001 From: Dave Woestenborghs Date: Fri, 27 Jul 2018 08:01:59 +0200 Subject: [PATCH 074/134] U4-10502 added dutch translations for user management --- src/Umbraco.Web.UI/umbraco/config/lang/nl.xml | 187 +++++++++++++++++- 1 file changed, 185 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml b/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml index f421dcf9f6..e271a11fe7 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml @@ -36,6 +36,10 @@ Sorteren Vertalen Bijwerken + Rechten instellen + Deblokkeer + Content sjabloon aanmaken + Uitnodiging opnieuw versturen Toegang geweigerd. @@ -1026,6 +1030,28 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Script view niet opgeslagen Er is een fout opgetreden bij het opslaan van dit bestand. Er is een fout opgetreden bij het opslaan van dit bestand. + %0% gebruikersgroepen verwijderd + %0% is verwijderd + %0% gebruikers geactiveerd + Er heeft zich een fout voorgedaan tijdens het activeren van de gebruikers + %0% users gedeactiveerd + Er heeft zich een fout voorgedaan tijdens het deactiveren van de gebruikers + %0% is nu geactiveerd + Er heeft zich een fout voorgedaan tijdens het activeren van de gebruiker + %0% is nu gedeactiveerd + Er heeft zich een fout voorgedaan tijdens het deactiveren van de gebruiker + Gebruikers groepen zijn ingesteld + %0% gebruikersgroepen verwijderd + %0% is verwijderd + %0% gebruikers gedeblokkeerd + Er heeft zich een fout voorgedaan tijdens het deblokkeren van de gebruikers + %0% is nu gedeblokkeerd + Er heeft zich een fout voorgedaan tijdens het deblokkeren van de gebruikers + Lid is geexporteerd naar een bestand + Er heeft zich een fout voorgedaan tijdens het exporteren van het lid + Gebruiker %0% is verwijderd + Gebruiker uitnodigen + Uitnodiging is opnieuw gestuurd naar gebruiker %0% Gebruik CSS syntax bijv: h1, .redHeader, .blueTex @@ -1287,23 +1313,45 @@ Om een vertalingstaak te sluiten, ga aub naar het detailoverzicht en klik op de Er is een fout opgetreden bij het zoeken naar een update. Bekijk de trace-stack voor verdere informatie. + Toegang + Gebaseerd op de gebruikers groepen en start pagina's heeft de bruiker toegang tot de volgende pagina's + Toegang geven Beheerders Categorieveld + Gebruiker aangemaakt Verander je wachtwoord + Wijzig je foto Wijzig je wachtwoord + is niet gedeblokkeerd + Het wachtwoord is niet gewijzigd Bevestig nieuw password Je kunt je wachtwoord veranderen door onderstaan formulier in te vullen en op de knop 'Verander wachtwoord' te klikken Inhoudskanaal + Nog een gebruiker aanmaken + Maak nieuwe gebruikers aan om hun toegang te geven tot Umbraco. Wanneer een nieuwe gebruiker wordt aangemaakt wordt er een wachtwoord gegenereerd dat je met hun kan delen. Omschrijving Geblokkeerde gebruiker Documenttype Redacteur Samenvattingsveld + Foute wachtwoord pogingen + Ga naar gebruikersprofiel + Voeg gebruikersgroepen toe om rechten in te stellen + Nog een gebruiker uitnodigen + Nodig gebruikers uit om hen toegang te geven to Umbraco. Een uitnodiging wordt via e-mail verstuurd met instructies hoe de gebruiker kan inloggen. Taal + Stel de taal in die gebruiker zal zien in menu's en dialoog vensters + Laatst geblokkeerd datu, + Laatste keer ingelogd + Laatste keer paswoord gewijzigd Loginnaam Startnode in Mediabibliotheek + Beperk de mediabibliotheek tot een specifieke startnode + Startnodes in Mediabibliotheek + Beperk de mediabibliotheek tot een specifieke startnodes Secties Blokkeer Umbraco toegang + heeft nog niet ingelogd Oude wachtwoord Wachtwoord Reset wachtwoord @@ -1318,16 +1366,151 @@ Om een vertalingstaak te sluiten, ga aub naar het detailoverzicht en klik op de Vervang rechten op de subitems U bent momenteel rechten aan het aanpassen voor volgende pagina's: Selecteer pagina's om hun rechten aan te passen - Doorzoek alle subitems - Startnode in Content + Verwijder je foto + Standaard rechten + Specifieke rechten + Geef rechten op specifieke nodes + Profiel + Doorzoek alle subitems + Geef de gebruiker toegang tot secties + Selecteer een gebruikersgroep + Geen startnode geselecteerd + Geen startnodes geselecteerd + Actief + Alles + Gedeactiveerd + Geblokkeerd + Uitgenodigd + Startnode in Content + Beperk de content toegan een specifieke start node + Startnodes in Content + Beperk de content toegan een specifieke start nodes + Naam (A-Z) + Naam (Z-A) + Nieuwste + Oudste + Laatste inlog + Laatste keer bijgewerkt + is aangemaakt + De gebruiker is aangemaakt. Om in te loggen in Umbraco gebruik je onderstaand wachtwoord. + Gebruikers beheren Gebruikersnaam Gebruikersrechten + Gebruikersgroep rechten + Gebruikersgroep + Gebruikersgroepen + is uitgenodigd + Een uitnodiging is gestuurd naar de nieuwe gebruiker met informatie over hoe in te loggen in Umbraco + Hallo en welk in Umbraco! Binnen ongeveer 1 minuut kan je aan de slag. Je moet enkel je wachtwoord instellen en een foto toevoegen. + Wijzig je foto zodat andere gebruikers je makkelijk kunnen herkennen. Auteur Vertaler Wijzig Je profiel Je recente historie Sessie verloopt over + Gebruiker uitnodigen + Gebruiker aanmaken + Uitnodiging versturen + Terug naar gebruikers + Umbraco: Uitnodiging + + + + + + + + +
+ + + +
+ + + + + +
+ +
+ +
+
+ + + + + + +
+
+
+ + + + +
+ + + + +
+

+ Hallo %0%, +

+

+ U bent uitgenodigd door %1% om in te loggen in de Umbraco Backoffice. +

+

+ Bericht van %1%: +
+ %2% +

+ + + + + + +
+ + + + + + +
+ + Klik hier om de uitnodiging te accepteren + +
+
+

Als je niet op de link kunt klikken, kopieer deze dan in de adresbalk van je browser:

+ + + + +
+ + %3% + +
+

+
+
+


+
+
+ + ]]> + + Uitnodigen + Uitnodiging opnieuw aan het versturen... + Verwijder gebruiker + Ben je zeker dat je deze gebruiker wil verwijderen? Validatie From f11c71599b7f3589f68efefb9df1cb38750c6a14 Mon Sep 17 00:00:00 2001 From: Claus Date: Fri, 27 Jul 2018 09:10:46 +0200 Subject: [PATCH 075/134] fixes U4-11536 Migration is breaking upgrade path to v. 7.12 --- .../IncreaseLanguageIsoCodeColumnLength.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/IncreaseLanguageIsoCodeColumnLength.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/IncreaseLanguageIsoCodeColumnLength.cs index 8f61c09af3..8a4a453cdf 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/IncreaseLanguageIsoCodeColumnLength.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/IncreaseLanguageIsoCodeColumnLength.cs @@ -13,10 +13,21 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwelveZ public override void Up() { + Execute.Code(database => + { + database.Execute("DROP INDEX [umbracoLanguage].[IX_umbracoLanguage_languageISOCode]"); + return null; + }); + Alter.Table("umbracoLanguage") .AlterColumn("languageISOCode") .AsString(14) .Nullable(); + + Create.Index("IX_umbracoLanguage_languageISOCode") + .OnTable("umbracoLanguage") + .OnColumn("languageISOCode") + .Unique(); } public override void Down() From 9b9173d64fde540cb9128cb2dd4db5499d6e654d Mon Sep 17 00:00:00 2001 From: BatJan Date: Fri, 27 Jul 2018 11:24:29 +0200 Subject: [PATCH 076/134] Use the umbConfirmAction directive when deleting tags (#2795) --- .../src/less/property-editors.less | 49 +++- .../propertyeditors/tags/tags.controller.js | 39 ++- .../src/views/propertyeditors/tags/tags.html | 50 ++-- src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 33 +-- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 225 ++++++++--------- .../umbraco/config/lang/en_us.xml | 227 +++++++++--------- 6 files changed, 342 insertions(+), 281 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 6ec097af2b..e88d792b13 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -3,20 +3,20 @@ // -------------------------------------------------- .umb-editor { min-width:66.6%; - + &-pull { float:left; width:66.6%; } - + &-push { float:right; - } + } } .umb-editor-tiny { width: 60px; - + &.umb-editor-push { width:30%; min-width:0; @@ -53,7 +53,7 @@ float:right; width:35%; } - + &--pull, &--push { .umb-editor { min-width:0; @@ -372,7 +372,7 @@ ul.color-picker li a { > li:not(.unsortable) { cursor: move; } -} +} .umb-sortable-thumbnails li:hover .umb-sortable-thumbnails__actions { opacity: 1; @@ -902,10 +902,39 @@ ul.color-picker li a { // // Tags // -------------------------------------------------- -.umb-tags{border: @gray-10 solid 1px; padding: 10px; font-size: 13px; text-shadow: none;} -.umb-tags .tag{cursor: pointer; margin: 7px; padding: 7px; background: @turquoise} -.umb-tags .tag i{padding: 2px;} -.umb-tags input{border: none; background: @white} +.umb-tags{ + border: @gray-10 solid 1px; + padding: 10px; + font-size: 13px; + text-shadow: none; + + .tag{ + cursor: default; + margin: 7px; + padding: 10px; + background: @turquoise; + position: relative; + + .icon-trash{ + cursor: pointer; + padding: 2px; + font-size: 12px; + position: relative; + right: -6px; + } + + .umb_confirm-action__overlay.-left{ + top: 6px; + left: auto; + right: 15px; + } + } + + input{ + border: none; + background: @white; + } +} // // Date/time picker diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js index 745fe48d0f..15a67629e6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js @@ -5,11 +5,11 @@ angular.module("umbraco") var $typeahead; $scope.isLoading = true; - $scope.tagToAdd = ""; - + $scope.tagToAdd = ""; + function setModelValue(val) { - - $scope.model.value = val || $scope.model.value; + + $scope.model.value = val || $scope.model.value; if ($scope.model.value) { if (!$scope.model.config.storageType || $scope.model.config.storageType !== "Json") { //it is csv @@ -20,9 +20,9 @@ angular.module("umbraco") if($scope.model.value.length > 0) { // split the csv string, and remove any duplicate values var tempArray = $scope.model.value.split(',').map(function(v) { - return v.trim(); + return v.trim(); }); - + $scope.model.value = tempArray.filter(function(v, i, self) { return self.indexOf(v) === i; }); @@ -40,7 +40,7 @@ angular.module("umbraco") $scope.isLoading = false; //load current value - setModelValue(); + setModelValue(); // Method required by the valPropertyValidator directive (returns true if the property editor has at least one tag selected) $scope.validateMandatory = function () { @@ -64,7 +64,7 @@ angular.module("umbraco") $scope.addTagOnEnter = function (e) { var code = e.keyCode || e.which; - if (code == 13) { //Enter keycode + if (code == 13) { //Enter keycode if ($element.find('.tags-' + $scope.model.alias).parent().find(".tt-dropdown-menu .tt-cursor").length === 0) { //this is required, otherwise the html form will attempt to submit. e.preventDefault(); @@ -83,17 +83,38 @@ angular.module("umbraco") $typeahead.typeahead('val', ''); }; - + // Set the visible prompt to -1 to ensure it will not be visible + $scope.promptIsVisible = "-1"; $scope.removeTag = function (tag) { var i = $scope.model.value.indexOf(tag); + if (i >= 0) { + // Make sure to hide the prompt so it does not stay open because another item gets a new number in the array index + $scope.promptIsVisible = "-1"; + + // Remove the tag from the index $scope.model.value.splice(i, 1); + //this is required to re-validate $scope.propertyForm.tagCount.$setViewValue($scope.model.value.length); } }; + $scope.showPrompt = function (idx, tag){ + + var i = $scope.model.value.indexOf(tag); + + // Make the prompt visible for the clicked tag only + if (i === idx) { + $scope.promptIsVisible = i; + } + } + + $scope.hidePrompt = function(){ + $scope.promptIsVisible = "-1"; + } + //vice versa $scope.model.onValueChanged = function (newVal, oldVal) { //update the display val again if it has changed from the server diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.html index 7e4de164de..18990b3e4a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.html @@ -1,27 +1,35 @@
- -
- Loading... -
-
+
+ Loading... +
- +
- - - - + - + + -
- -
\ No newline at end of file + + + + + + + + +
+ +
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index 0ea581230c..90a8d574f4 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -132,6 +132,7 @@ Gem og generer modeller Fortryd Genskab + Slet tag For @@ -153,7 +154,7 @@ Indhold tilbagerullet Sendt til udgivelse Sendt til oversættelse - + For at skifte det valgte indholds dokumenttype, skal du først vælge en ny dokumenttype, som er gyldig på denne placering. Kontroller derefter, at alle egenskaber bliver overført rigtigt til den nye dokumenttype, og klik derefter på Gem. @@ -211,7 +212,7 @@ Dette dokument er udgivet, men dets url ville kollidere med indholdet %0% Udgiv Udgivet - Udgivet (Ventede ændringer) + Udgivet (Ventede ændringer) Udgivet Udgivelsesstatus Udgivelsesdato @@ -985,7 +986,7 @@ Mange hilsner fra Umbraco robotten Nulstil - + Nuværende version @@ -1149,19 +1150,19 @@ Mange hilsner fra Umbraco robotten Makro - En makro er et element, som kan have forskellige indstillinger, når det indsættes. + En makro er et element, som kan have forskellige indstillinger, når det indsættes. Brug det som en genbrugelig del af dit design såsom gallerier, formularer og lister. Sideværdi - Viser værdien af et felt fra den nuværende side. Kan indstilles til at bruge rekursive værdier eller + Viser værdien af et felt fra den nuværende side. Kan indstilles til at bruge rekursive værdier eller vise en standardværdi i tilfælde af, at feltet er tomt. Partial view - Et Partial View er et skabelonelement, som kan indsættes i andre skabeloner og derved + Et Partial View er et skabelonelement, som kan indsættes i andre skabeloner og derved genbruges og deles på tværs af sideskabelonerne. @@ -1172,7 +1173,7 @@ Mange hilsner fra Umbraco robotten Indsæt en underliggende skabelon @RenderBody() element. ]]> @@ -1181,8 +1182,8 @@ Mange hilsner fra Umbraco robotten Definer en sektion @section { ... }. Herefter kan denne sektion flettes ind i + Definerer en del af din skabelon som en navngivet sektion, ved at + omkranse den i @section { ... }. Herefter kan denne sektion flettes ind i overliggende skabelon ved at indsætte et @RenderSection element. ]]> @@ -1190,15 +1191,15 @@ Mange hilsner fra Umbraco robotten Indsæt en sektion @RenderSection(name) element. Den underliggende skabelon skal have + Henter indholdet af en sektion fra den underliggende skabelon ind, ved at indsætte et + @RenderSection(name) element. Den underliggende skabelon skal have defineret en sektion via et @section [name]{ ... } element. ]]> Sektionsnavn Sektionen er obligatorisk - + Hvis obligatorisk, skal underskabelonen indeholde en @section -definition. @@ -1210,7 +1211,7 @@ Mange hilsner fra Umbraco robotten Returner alt indhold indhold af typen "%0%" - + fra mit website hvor @@ -1242,14 +1243,14 @@ Mange hilsner fra Umbraco robotten Skabelon - + Rich Text Editor Billede Macro Embed Overskrift - Citat + Citat Vælg indholdstype Vælg layout Tilføj række @@ -1601,4 +1602,4 @@ Mange hilsner fra Umbraco robotten Karakterer tilbage - \ No newline at end of file + diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index b0548bae93..0d24970c54 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -138,6 +138,7 @@ Save and generate models Undo Redo + Delete tag Viewing for @@ -920,41 +921,41 @@ To manage your website, simply open the Umbraco back office and start adding con Umbraco: Reset Password - - - - - - + + + + + + + - - + +
+
- - - + + + -
- -
- -
+ +
+ +
-
+ - + - - - + + +
+

- - + + -
+
- - + +
+

Password reset requested

@@ -964,12 +965,12 @@ To manage your website, simply open the Umbraco back office and start adding con

- - + + +
+
Click this link to reset your password - -
@@ -981,22 +982,22 @@ To manage your website, simply open the Umbraco back office and start adding con %1% -

-
-
+ - -


-
- - + +


+
+ + - + ]]> @@ -1040,53 +1041,53 @@ To manage your website, simply open the Umbraco back office and start adding con - - - - - - + + + + + + + - - + +
+
- - + + -
- -
- -
+ +
+ +
-
+ - + - - - + + -
+

- - + - +
+
- - +
+

Hi %0%,

-

+

This is an automated mail to inform you that the task '%1%' has been performed on the page '%2%' by the user '%3%'

- - @@ -1096,7 +1097,7 @@ To manage your website, simply open the Umbraco back office and start adding con

Update summary:

+ +
EDIT
%6% -
+

Have a nice day!

@@ -1108,10 +1109,10 @@ To manage your website, simply open the Umbraco back office and start adding con

-


+


@@ -1681,7 +1682,7 @@ To manage your website, simply open the Umbraco back office and start adding con Allow this property value to be displayed on the member profile page tab has no sort order - + Where is this composition used? This composition is currently used in the composition of the following content types: @@ -1936,41 +1937,41 @@ To manage your website, simply open the Umbraco back office and start adding con Umbraco: Invitation - - - - - - + + + + + + + - - + +
+
- - - + + + -
- -
- -
+ +
+ +
-
+
+ - - - + + +
+

- - + + -
+
- - + +
+

Hi %0%,

@@ -1988,12 +1989,12 @@ To manage your website, simply open the Umbraco back office and start adding con
- - + + +
+
Click this link to accept the invite - -
@@ -2008,22 +2009,22 @@ To manage your website, simply open the Umbraco back office and start adding con %3% -

-
-
+ - -


-
- - + +


+
+ + - + ]]> 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 e70c66b119..cbb86697c8 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -138,6 +138,7 @@ Save and generate models Undo Redo + Delete tag Viewing for @@ -918,41 +919,41 @@ To manage your website, simply open the Umbraco back office and start adding con Umbraco: Reset Password - - - - - - + + + + + + + - - + +
+
- - - + + + -
- -
- -
+ +
+ +
-
+ - + - - - + + +
+

- - + + -
+
- - + +
+

Password reset requested

@@ -962,12 +963,12 @@ To manage your website, simply open the Umbraco back office and start adding con

- - + + +
+
Click this link to reset your password - -
@@ -979,22 +980,22 @@ To manage your website, simply open the Umbraco back office and start adding con %1% -

-
-
+ - -


-
- - + +


+
+ + - + ]]> @@ -1038,53 +1039,53 @@ To manage your website, simply open the Umbraco back office and start adding con - - - - - - + + + + + + + - - + +
+
- - + + -
- -
- -
+ +
+ +
-
+ - + - - - + + -
+

- - + - +
+
- - +
+

Hi %0%,

-

+

This is an automated mail to inform you that the task '%1%' has been performed on the page '%2%' by the user '%3%'

- - @@ -1094,7 +1095,7 @@ To manage your website, simply open the Umbraco back office and start adding con

Update summary:

+ +
EDIT
%6% -
+

Have a nice day!

@@ -1106,10 +1107,10 @@ To manage your website, simply open the Umbraco back office and start adding con

-


+


@@ -1273,7 +1274,7 @@ To manage your website, simply open the Umbraco back office and start adding con You have picked a media item currently deleted or in the recycle bin You have picked media items currently deleted or in the recycle bin Deleted item - Trashed + Trashed enter external link @@ -1674,7 +1675,7 @@ To manage your website, simply open the Umbraco back office and start adding con Allow this property value to be displayed on the member profile page tab has no sort order - + Where is this composition used? This composition is currently used in the composition of the following content types: @@ -1929,41 +1930,41 @@ To manage your website, simply open the Umbraco back office and start adding con Umbraco: Invitation - - - - - - + + + + + + + - - + +
+
- - - + + + -
- -
- -
+ +
+ +
-
+
+ - - - + + +
+

- - + + -
+
- - + +
+

Hi %0%,

@@ -1981,12 +1982,12 @@ To manage your website, simply open the Umbraco back office and start adding con
- - + + +
+
Click this link to accept the invite - -
@@ -2001,22 +2002,22 @@ To manage your website, simply open the Umbraco back office and start adding con %3% -

-
-
+ - -


-
- - + +


+
+ + - + ]]> From e920d3f4b22429a529a61f2384adc7aec827dbc7 Mon Sep 17 00:00:00 2001 From: Lotte Pitcher Date: Fri, 27 Jul 2018 11:39:27 +0100 Subject: [PATCH 077/134] In build.ps1, use .Path if .Source returns nothing --- build/build.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/build/build.ps1 b/build/build.ps1 index 3134dfedb2..5f85284431 100644 --- a/build/build.ps1 +++ b/build/build.ps1 @@ -62,6 +62,7 @@ $global:node_path = $env:path $nodePath = $this.BuildEnv.NodePath $gitExe = (Get-Command git).Source + if (-not $gitExe) { $gitExe = (Get-Command git).Path } $gitPath = [System.IO.Path]::GetDirectoryName($gitExe) $env:path = "$nodePath;$gitPath" From f7e097be8ee8c943b21b959f3d8945c8d3dfd9ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Sougnez?= Date: Fri, 27 Jul 2018 12:50:30 +0200 Subject: [PATCH 078/134] Minor update to the grid settings/style section (#2797) --- .../propertyeditors/grid/grid.prevalues.html | 76 ++++++++----------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.html index fa2da2f9e2..539433821b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.html @@ -2,7 +2,7 @@
-

+

    - +
@@ -57,13 +57,13 @@
  • + class="preview-rows columns" style="margin-top: 5px; margin-bottom: 25px; float:left">
    + ng-class="{last:$last}" + ng-repeat="area in layout.areas | filter:zeroWidthFilter" + ng-style="{width: percentage(area.grid) + '%', 'max-width': '100%'}">

    {{area.maxItems}}

    @@ -95,15 +95,13 @@
    - - + + - +
    - + - + - + - +
    From b8af6f79877473d615584c8399ad01d789cc6e34 Mon Sep 17 00:00:00 2001 From: Jan Skovgaard Date: Fri, 27 Jul 2018 13:03:12 +0200 Subject: [PATCH 079/134] Add title attributes to the "buttons" inside the umbConfirmAction directive providing translations for english and danish at the same time --- .../src/views/components/umb-confirm-action.html | 4 ++-- src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 2 ++ src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 2 ++ src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 2 ++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm-action.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm-action.html index c34c3f9283..f4e4dff3af 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm-action.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm-action.html @@ -6,11 +6,11 @@ '-left': direction === 'left'}" on-outside-click="clickCancel()"> - + - +
    diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index 90a8d574f4..c039c2b5b9 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -133,6 +133,8 @@ Fortryd Genskab Slet tag + Fortryd + Bekræft For diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 0d24970c54..eb514a62f7 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -139,6 +139,8 @@ Undo Redo Delete tag + Cancel + Confirm Viewing for 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 cbb86697c8..77dd604bd0 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -139,6 +139,8 @@ Undo Redo Delete tag + Cancel + Confirm Viewing for From 9162be9fb0aaa8fdb87490a832be76d3b422f944 Mon Sep 17 00:00:00 2001 From: Callum Whyte Date: Fri, 27 Jul 2018 13:01:54 +0100 Subject: [PATCH 080/134] Updating template query builder to use new APIs --- .../Editors/TemplateQueryController.cs | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web/Editors/TemplateQueryController.cs b/src/Umbraco.Web/Editors/TemplateQueryController.cs index 26ca518259..e38c0a1b26 100644 --- a/src/Umbraco.Web/Editors/TemplateQueryController.cs +++ b/src/Umbraco.Web/Editors/TemplateQueryController.cs @@ -1,13 +1,13 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Services; +using Umbraco.Web.Models.TemplateQuery; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi; -using System; -using System.Diagnostics; -using Umbraco.Core.Models.PublishedContent; -using Umbraco.Web.Models.TemplateQuery; -using Umbraco.Core.Services; namespace Umbraco.Web.Editors { @@ -66,7 +66,7 @@ namespace Umbraco.Web.Editors var sb = new StringBuilder(); var indention = Environment.NewLine + "\t\t\t\t\t\t"; - sb.Append("Model.Content.Site()"); + sb.Append("Model.Root()"); var timer = new Stopwatch(); @@ -103,7 +103,7 @@ namespace Umbraco.Web.Editors { // we did not find the path sb.Clear(); - sb.AppendFormat("Umbraco.TypedContent({0})", model.Source.Id); + sb.AppendFormat("Umbraco.Content({0})", model.Source.Id); pointerNode = targetNode; } } @@ -195,10 +195,16 @@ namespace Umbraco.Web.Editors timer.Stop(); - var direction = model.Sort.Direction == "ascending" ? string.Empty : " desc"; - sb.Append(indention); - sb.AppendFormat(".OrderBy(\"{0}{1}\")", model.Sort.Property.Alias, direction); + + if (model.Sort.Direction == "ascending") + { + sb.AppendFormat(".OrderBy(x => x.{0})", model.Sort.Property.Alias); + } + else + { + sb.AppendFormat(".OrderByDescending(x => x.{0})", model.Sort.Property.Alias); + } } if (model.Take > 0) @@ -293,7 +299,7 @@ namespace Umbraco.Web.Editors public IEnumerable GetContentTypes() { var contentTypes = Services.ContentTypeService.GetAll() - .Select(x => new ContentTypeModel { Alias = x.Alias, Name = Services.TextService.Localize("template/contentOfType", tokens: new string[] { x.Name } ) }) + .Select(x => new ContentTypeModel { Alias = x.Alias, Name = Services.TextService.Localize("template/contentOfType", tokens: new string[] { x.Name }) }) .OrderBy(x => x.Name).ToList(); contentTypes.Insert(0, new ContentTypeModel { Alias = string.Empty, Name = Services.TextService.Localize("template/allContent") }); From 154d36e5804c721ea1568dfbcd8fbfdc096b84be Mon Sep 17 00:00:00 2001 From: Callum Whyte Date: Fri, 27 Jul 2018 13:02:37 +0100 Subject: [PATCH 081/134] Cleanup of template query builder whitespace --- .../src/common/services/templatehelper.service.js | 3 ++- src/Umbraco.Web/Editors/TemplateQueryController.cs | 5 +---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/templatehelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/templatehelper.service.js index 6fc20524e9..2e71ef0bf5 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/templatehelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/templatehelper.service.js @@ -22,7 +22,8 @@ function getQuerySnippet(queryExpression) { var code = "\n@{\n" + "\tvar selection = " + queryExpression + ";\n}\n"; code += "
      \n" + - "\t@foreach(var item in selection){\n" + + "\t@foreach (var item in selection)\n" + + "\t{\n" + "\t\t
    • \n" + "\t\t\t@item.Name\n" + "\t\t
    • \n" + diff --git a/src/Umbraco.Web/Editors/TemplateQueryController.cs b/src/Umbraco.Web/Editors/TemplateQueryController.cs index e38c0a1b26..f614d38ecb 100644 --- a/src/Umbraco.Web/Editors/TemplateQueryController.cs +++ b/src/Umbraco.Web/Editors/TemplateQueryController.cs @@ -255,12 +255,10 @@ namespace Umbraco.Web.Editors ? contents.OrderBy(x => x.Id) : contents.OrderByDescending(x => x.Id); case "createDate": - return sortExpression.Direction == "ascending" ? contents.OrderBy(x => x.CreateDate) : contents.OrderByDescending(x => x.CreateDate); case "publishDate": - return sortExpression.Direction == "ascending" ? contents.OrderBy(x => x.UpdateDate) : contents.OrderByDescending(x => x.UpdateDate); @@ -269,7 +267,6 @@ namespace Umbraco.Web.Editors ? contents.OrderBy(x => x.Name) : contents.OrderByDescending(x => x.Name); default: - return sortExpression.Direction == "ascending" ? contents.OrderBy(x => x.Name) : contents.OrderByDescending(x => x.Name); @@ -281,10 +278,10 @@ namespace Umbraco.Web.Editors var aliases = new List(); if (targetNode == null || targetNode.Id == current.Id) return aliases; + if (targetNode.Id != current.Id) { aliases.Add(targetNode.ContentType.Alias); - } aliases.AddRange(this.GetChildContentTypeAliases(targetNode.Parent, current)); From bd3f7ffcd463943a9e35368ebffea4ec590c1c22 Mon Sep 17 00:00:00 2001 From: BatJan Date: Fri, 27 Jul 2018 14:35:04 +0200 Subject: [PATCH 082/134] U4-11538 Color picker thumbnail is to wide (#2801) --- src/Umbraco.Web.UI.Client/src/less/property-editors.less | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index e88d792b13..5fb7f4cfc9 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -138,6 +138,12 @@ ul.color-picker li { margin: 3px; border: 2px solid transparent; width: 60px; + + .thumbnail{ + min-width: auto; + width: 58px; + padding: 0; + } } ul.color-picker li.active { border: 2px dashed @gray-8; From 344b67d23690dcd689115f78b7ce028ed0934c60 Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 27 Jul 2018 13:45:09 +0100 Subject: [PATCH 083/134] Removed unused files --- .../Migrations/SqlScripts/MySqlTotal-480.sql | 1 - .../SqlScripts/SqlServerTotal-480.sql | 5 +- .../Mvc/ReflectedFixedRazorViewEngine.cs | 99 ----------- src/Umbraco.Web/Mvc/RenderViewEngine.cs | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 5 +- .../UmbracoBackOfficeLogoutAttribute.cs | 17 -- .../umbraco/Trees/loadPackager.cs | 158 ------------------ 7 files changed, 4 insertions(+), 283 deletions(-) delete mode 100644 src/Umbraco.Web/Mvc/ReflectedFixedRazorViewEngine.cs delete mode 100644 src/Umbraco.Web/WebApi/Filters/UmbracoBackOfficeLogoutAttribute.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadPackager.cs diff --git a/src/Umbraco.Tests/Migrations/SqlScripts/MySqlTotal-480.sql b/src/Umbraco.Tests/Migrations/SqlScripts/MySqlTotal-480.sql index 7cd05ec6b2..0967f116b0 100644 --- a/src/Umbraco.Tests/Migrations/SqlScripts/MySqlTotal-480.sql +++ b/src/Umbraco.Tests/Migrations/SqlScripts/MySqlTotal-480.sql @@ -550,7 +550,6 @@ INSERT INTO umbracoAppTree (appAlias, treeAlias, treeSilent, treeInitialize, tre ('developer', 'macros', 0, 1, 2, 'Macros', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMacros'), ('developer', 'xslt', 0, 1, 5, 'XSLT Files', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadXslt'), - ('developer', 'packager', 0, 1, 3, 'Packages', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadPackager'), ('developer', 'packagerPackages', 0, 0, 1, 'Packager Packages', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadPackages'), ('media', 'media', 0, 1, 0, 'Medier', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadMedia'), diff --git a/src/Umbraco.Tests/Migrations/SqlScripts/SqlServerTotal-480.sql b/src/Umbraco.Tests/Migrations/SqlScripts/SqlServerTotal-480.sql index 3fb0914852..e69d87f759 100644 --- a/src/Umbraco.Tests/Migrations/SqlScripts/SqlServerTotal-480.sql +++ b/src/Umbraco.Tests/Migrations/SqlScripts/SqlServerTotal-480.sql @@ -879,8 +879,7 @@ values (4,1041,'default', 0, 'group') SET IDENTITY_INSERT [cmsDataTypePreValues] OFF ; /* 3.1 SQL changes */ -INSERT INTO [umbracoAppTree] ([appAlias], [treeAlias], [treeSilent], [treeInitialize], [treeSortOrder], [treeTitle], [treeIconClosed], [treeIconOpen], [treeHandlerAssembly], [treeHandlerType]) VALUES (N'developer', N'packager', 0, 1, 3, N'Packages', N'folder.gif', N'folder_o.gif', N'umbraco', N'loadPackager') -; + INSERT INTO [umbracoAppTree] ([appAlias], [treeAlias], [treeSilent], [treeInitialize], [treeSortOrder], [treeTitle], [treeIconClosed], [treeIconOpen], [treeHandlerAssembly], [treeHandlerType]) VALUES (N'developer', N'packagerPackages', 0, 0, 1, N'Packager Packages', N'folder.gif', N'folder_o.gif', N'umbraco', N'loadPackages'); @@ -1669,4 +1668,4 @@ ALTER TABLE cmsMember2MemberGroup ADD CONSTRAINT END OF NEW CONSTRAINTS -***********************************************************************************************************************/ \ No newline at end of file +***********************************************************************************************************************/ diff --git a/src/Umbraco.Web/Mvc/ReflectedFixedRazorViewEngine.cs b/src/Umbraco.Web/Mvc/ReflectedFixedRazorViewEngine.cs deleted file mode 100644 index b3a1904efe..0000000000 --- a/src/Umbraco.Web/Mvc/ReflectedFixedRazorViewEngine.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Reflection; -using System.Web.Mvc; - -namespace Umbraco.Web.Mvc -{ - /// - /// This is here to support compatibility with both MVC4 and MVC5 - /// - [Obsolete("MVC5 does not have a 'fixed' viewengine so there's no reason to use this any more", false)] - public abstract class ReflectedFixedRazorViewEngine : IViewEngine - { - protected ReflectedFixedRazorViewEngine() - { - if (MvcVersionCheck.MvcVersion >= System.Version.Parse("5.0.0")) - { - _wrappedEngine = new RazorViewEngine(); - } - else - { - var assembly = Assembly.Load("Microsoft.Web.Mvc.FixedDisplayModes"); - var engineType = assembly.GetType("Microsoft.Web.Mvc.FixedRazorViewEngine"); - _wrappedEngine = (IViewEngine)Activator.CreateInstance(engineType); - } - } - - public string[] ViewLocationFormats - { - get { return _viewLocationFormats; } - set - { - _wrappedEngine.GetType().GetProperty("ViewLocationFormats").SetValue(_wrappedEngine, value); - _viewLocationFormats = value; - } - } - - public string[] PartialViewLocationFormats - { - get { return _partialViewLocationFormats; } - set - { - _wrappedEngine.GetType().GetProperty("PartialViewLocationFormats").SetValue(_wrappedEngine, value); - _partialViewLocationFormats = value; - } - } - - public string[] AreaViewLocationFormats - { - get { return _areaViewLocationFormats; } - set - { - _wrappedEngine.GetType().GetProperty("AreaViewLocationFormats").SetValue(_wrappedEngine, value); - _areaViewLocationFormats = value; - } - } - - public string[] AreaMasterLocationFormats - { - get { return _areaMasterLocationFormats; } - set - { - _wrappedEngine.GetType().GetProperty("AreaMasterLocationFormats").SetValue(_wrappedEngine, value); - _areaMasterLocationFormats = value; - } - } - - public string[] AreaPartialViewLocationFormats - { - get { return _areaPartialViewLocationFormats; } - set - { - _wrappedEngine.GetType().GetProperty("AreaPartialViewLocationFormats").SetValue(_wrappedEngine, value); - _areaPartialViewLocationFormats = value; - } - } - - private readonly IViewEngine _wrappedEngine; - private string[] _areaViewLocationFormats; - private string[] _areaMasterLocationFormats; - private string[] _areaPartialViewLocationFormats; - private string[] _viewLocationFormats; - private string[] _partialViewLocationFormats; - - public virtual ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) - { - return _wrappedEngine.FindPartialView(controllerContext, partialViewName, useCache); - } - - public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) - { - return _wrappedEngine.FindView(controllerContext, viewName, masterName, useCache); - } - - public void ReleaseView(ControllerContext controllerContext, IView view) - { - _wrappedEngine.ReleaseView(controllerContext, view); - } - } -} diff --git a/src/Umbraco.Web/Mvc/RenderViewEngine.cs b/src/Umbraco.Web/Mvc/RenderViewEngine.cs index b3a6856bd9..0fa22616b2 100644 --- a/src/Umbraco.Web/Mvc/RenderViewEngine.cs +++ b/src/Umbraco.Web/Mvc/RenderViewEngine.cs @@ -12,7 +12,7 @@ namespace Umbraco.Web.Mvc /// A view engine to look into the template location specified in the config for the front-end/Rendering part of the cms, /// this includes paths to render partial macros and media item templates. /// - public class RenderViewEngine : ReflectedFixedRazorViewEngine + public class RenderViewEngine : RazorViewEngine { private readonly IEnumerable _supplementedViewLocations = new[] { "/{0}.cshtml" }; //NOTE: we will make the main view location the last to be searched since if it is the first to be searched and there is both a view and a partial diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 581c0ae815..dc45a0b051 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -576,7 +576,6 @@ - @@ -803,7 +802,6 @@ ASPXCodeBehind - True @@ -824,7 +822,6 @@ - @@ -1580,4 +1577,4 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web/WebApi/Filters/UmbracoBackOfficeLogoutAttribute.cs b/src/Umbraco.Web/WebApi/Filters/UmbracoBackOfficeLogoutAttribute.cs deleted file mode 100644 index c8dd64c83c..0000000000 --- a/src/Umbraco.Web/WebApi/Filters/UmbracoBackOfficeLogoutAttribute.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.ComponentModel; -using System.Web.Http.Filters; -using Umbraco.Core.Security; - -namespace Umbraco.Web.WebApi.Filters -{ - [Obsolete("This is no longer used and will be removed from the codebase in the future, use OWIN IAuthenticationManager.SignOut instead", true)] - [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class UmbracoBackOfficeLogoutAttribute : ActionFilterAttribute - { - public override void OnActionExecuted(HttpActionExecutedContext context) - { - throw new NotSupportedException("This method is not supported and should not be used, it has been removed in Umbraco 7.4"); - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadPackager.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadPackager.cs deleted file mode 100644 index f7f6acc068..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadPackager.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Umbraco.Core; -using Umbraco.Core.Services; -using umbraco.cms.presentation.Trees; -using Umbraco.Web.Trees; -using Umbraco.Web._Legacy.Actions; - -namespace umbraco -{ - /// - /// Handles loading of the packager application into the developer application tree - /// - //[Tree(Constants.Applications.Developer, "packager", "Packages", sortOrder: 3)] - [Obsolete("This is no longer used and will be removed from the codebase in the future")] - public class loadPackager : BaseTree - { - public loadPackager(string application) : base(application) { } - protected override void CreateRootNode(ref XmlTreeNode rootNode) - { - - } - - private int _id; - private string _app; - - /// - /// Sets the id. - /// - /// The id. - public override int id - { - set { _id = value; } - } - - /// - /// Sets the app. - /// - /// The app. - public override string app - { - set { _app = value; } - } - - protected override void CreateAllowedActions(ref List actions) - { - actions.Clear(); - actions.Add(ActionRefresh.Instance); - } - - protected override void CreateRootNodeActions(ref List actions) - { - actions.Clear(); - - // U4-4422 : There is no variable nodes on this so no need to reload nodes - //actions.Add(umbraco.BusinessLogic.Actions.ActionRefresh.Instance); - } - - /// - /// Renders the Javascript. - /// - /// The javascript. - public override void RenderJS(ref StringBuilder Javascript) - { - Javascript.Append( - @"function openPackageCategory(url) { - UmbClientMgr.contentFrame('developer/packages/' + url);}" - ); - } - - /// - /// Renders the specified tree item. - /// - /// The tree. - public override void Render(ref XmlTree tree) - { - string[,] items = { { "BrowseRepository.aspx", "Install from repository" }, { "CreatePackage.aspx", "Created Packages" }, { "installedPackages.aspx", "Installed packages" }, { "StarterKits.aspx", "Starter kit" }, { "installer.aspx", "Install local package" } }; - - for (var i = 0; i <= items.GetUpperBound(0); i++) - { - var xNode = XmlTreeNode.Create(this); - xNode.NodeID = (i + 1).ToInvariantString(); - xNode.Text = items[i, 1]; - xNode.Icon = "icon-folder"; - xNode.OpenIcon = "icon-folder"; - - - //Make sure the different sections load the correct childnodes. - switch (items[i, 0]) - { - case "installedPackages.aspx": - - if (cms.businesslogic.packager.InstalledPackage.GetAllInstalledPackages().Count > 0) - { - xNode.Source = $"tree.aspx?app={_app}&id={_id}&treeType=packagerPackages&packageType=installed&rnd={Guid.NewGuid()}"; - xNode.NodeType = "installedPackages"; - xNode.Text = Services.TextService.Localize("treeHeaders/installedPackages"); - xNode.HasChildren = true; - } - else - { - xNode.Text = ""; - } - xNode.Action = "javascript:void(0);"; - break; - - - case "BrowseRepository.aspx": - xNode.Text = Constants.PackageRepository.DefaultRepositoryName; - xNode.Source = $"tree.aspx?app={_app}&id={_id}&treeType=packagerPackages&packageType=repository&repoGuid={Constants.PackageRepository.DefaultRepositoryId}&rnd={Guid.NewGuid()}"; - - xNode.NodeType = "packagesRepository"; - xNode.Action = $"javascript:openPackageCategory(\'BrowseRepository.aspx?repoGuid={Constants.PackageRepository.DefaultRepositoryId}\');"; - xNode.Icon = "icon-server-alt"; - xNode.HasChildren = true; - break; - - case "CreatePackage.aspx": - xNode.Source = $"tree.aspx?app={_app}&id={_id}&treeType=packagerPackages&packageType=created&rnd={Guid.NewGuid()}"; - xNode.NodeType = "createdPackages"; - xNode.Menu.Clear(); - xNode.Menu.Add(ActionNew.Instance); - xNode.Menu.Add(ActionRefresh.Instance); - xNode.Text = Services.TextService.Localize("treeHeaders/createdPackages"); - xNode.HasChildren = true; - xNode.Action = "javascript:void(0);"; - break; - - case "installer.aspx": - xNode.Source = ""; - xNode.NodeType = "uploadPackage"; - xNode.Icon = "icon-page-up"; - xNode.Action = $"javascript:openPackageCategory(\'{items[i, 0]}\');"; - xNode.Text = Services.TextService.Localize("treeHeaders/localPackage"); - xNode.Menu.Clear(); - break; - - case "StarterKits.aspx": - xNode.Source = ""; - xNode.NodeType = "starterKits"; - xNode.Action = $"javascript:openPackageCategory(\'{items[i, 0]}\');"; - xNode.Icon = "icon-flash"; - xNode.Text = Services.TextService.Localize("treeHeaders/installStarterKit"); - xNode.Menu.Clear(); - break; - - default: - break; - } - - if (xNode.Text != "") - tree.Add(xNode); - } - - } - } -} From 8c1f236e3f384b34ed0ff1543fb6670cb2fe0587 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 27 Jul 2018 15:08:48 +0200 Subject: [PATCH 084/134] Fix unit test --- .../PropertyEditors/MultiValuePropertyEditorTests.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs index 42b9d174df..0062dbdce2 100644 --- a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs @@ -5,6 +5,7 @@ using NUnit.Framework; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; +using Umbraco.Tests.TestHelpers; using Umbraco.Web.PropertyEditors; namespace Umbraco.Tests.PropertyEditors @@ -14,7 +15,7 @@ namespace Umbraco.Tests.PropertyEditors /// multiple values such as the drop down list, check box list, color picker, etc.... /// [TestFixture] - public class MultiValuePropertyEditorTests + public class MultiValuePropertyEditorTests : BaseUmbracoApplicationTest { //TODO: Test the other formatting methods for the drop down classes @@ -111,4 +112,4 @@ namespace Umbraco.Tests.PropertyEditors } } -} \ No newline at end of file +} From 675ce08469d7e21f87e04b0836841210aaabafb5 Mon Sep 17 00:00:00 2001 From: Adam Shallcross Date: Fri, 27 Jul 2018 14:09:51 +0100 Subject: [PATCH 085/134] Updated the umbraco.org URL's to be umbraco.com --- docs/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index 64282ea2e8..47270a54a3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,11 +17,11 @@ Umbraco is a free open source Content Management System built on the ASP.NET pla ## Umbraco - The Friendly CMS -For the first time on the Microsoft platform, there is a free user and developer friendly CMS that makes it quick and easy to create websites - or a breeze to build complex web applications. Umbraco has award-winning integration capabilities and supports ASP.NET MVC or Web Forms, including User and Custom Controls, out of the box. +For the first time on the Microsoft platform, there is a free user and developer friendly CMS that makes it quick and easy to create websites - or a breeze to build complex web applications. Umbraco has award-winning integration capabilities and supports ASP.NET MVC or Web Forms, including User and Custom Controls, out of the box. Umbraco is not only loved by developers, but is a content editors dream. Enjoy intuitive editing tools, media management, responsive views and approval workflows to send your content live. -Used by more than 443,000 active websites including Carlsberg, Segway, Amazon and Heinz and **The Official ASP.NET and IIS.NET website from Microsoft** ([https://asp.net](https://asp.net) / [https://iis.net](https://iis.net)), you can be sure that the technology is proven, stable and scales. Backed by the team at Umbraco HQ, and supported by a dedicated community of over 220,000 craftspeople globally, you can trust that Umbraco is a safe choice and is here to stay. +Used by more than 443,000 active websites including Carlsberg, Segway, Amazon and Heinz and **The Official ASP.NET and IIS.NET website from Microsoft** ([https://asp.net](https://asp.net) / [https://iis.net](https://iis.net)), you can be sure that the technology is proven, stable and scales. Backed by the team at Umbraco HQ, and supported by a dedicated community of over 220,000 craftspeople globally, you can trust that Umbraco is a safe choice and is here to stay. To view more examples, please visit [https://umbraco.com/why-umbraco/#caseStudies](https://umbraco.com/why-umbraco/#caseStudies) @@ -32,11 +32,11 @@ As an Open Source platform, Umbraco is more than just a CMS. We are transparent [Umbraco Cloud](https://umbraco.com) is the easiest and fastest way to use Umbraco yet with full support for all your custom .NET code and intergrations. You're up and running in less than a minute and your life will be made easier with automated upgrades and a built-in deployment engine. We offer a free 14 day trial, no credit card needed. -If you want to DIY you can [download Umbraco](https://our.umbraco.org/download) either as a ZIP file or via NuGet. It's the same version of Umbraco CMS that powers Umbraco Cloud, but you'll need to find a place to host yourself and handling deployments and upgrades is all down to you. +If you want to DIY you can [download Umbraco](https://our.umbraco.com/download) either as a ZIP file or via NuGet. It's the same version of Umbraco CMS that powers Umbraco Cloud, but you'll need to find a place to host yourself and handling deployments and upgrades is all down to you. ## Community -Our friendly community is available 24/7 at the community hub we call ["Our Umbraco"](https://our.umbraco.org). Our Umbraco feature forums for questions and answers, documentation, downloadable plugins for Umbraco and a rich collection of community resources. +Our friendly community is available 24/7 at the community hub we call ["Our Umbraco"](https://our.umbraco.com). Our Umbraco feature forums for questions and answers, documentation, downloadable plugins for Umbraco and a rich collection of community resources. ## Contribute to Umbraco @@ -44,6 +44,6 @@ Umbraco is contribution focused and community driven. If you want to contribute ## Found a bug? -Another way you can contribute to Umbraco is by providing issue reports. For information on how to submit an issue report refer to our [online guide for reporting issues](https://our.umbraco.org/contribute/report-an-issue-or-request-a-feature). +Another way you can contribute to Umbraco is by providing issue reports. For information on how to submit an issue report refer to our [online guide for reporting issues](https://our.umbraco.com/contribute/report-an-issue-or-request-a-feature). To view existing issues, please visit [http://issues.umbraco.org](http://issues.umbraco.org). From 3f7a5d18f8a225b1144416f7ab5e3da3ad11faa6 Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 27 Jul 2018 14:17:41 +0100 Subject: [PATCH 086/134] Refactored out some obsolete methods --- src/Umbraco.Core/Services/IFileService.cs | 15 --------- .../Services/Implement/FileService.cs | 31 ------------------- .../Templates/TemplateUtilities.cs | 17 +--------- src/Umbraco.Web/UmbracoComponentRenderer.cs | 2 +- .../umbraco.presentation/default.aspx.cs | 2 +- 5 files changed, 3 insertions(+), 64 deletions(-) diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs index a61faa10c7..76e850beb2 100644 --- a/src/Umbraco.Core/Services/IFileService.cs +++ b/src/Umbraco.Core/Services/IFileService.cs @@ -169,21 +169,6 @@ namespace Umbraco.Core.Services /// IEnumerable GetTemplateChildren(int masterTemplateId); - /// - /// Returns a template as a template node which can be traversed (parent, children) - /// - /// - /// - TemplateNode GetTemplateNode(string alias); - - /// - /// Given a template node in a tree, this will find the template node with the given alias if it is found in the hierarchy, otherwise null - /// - /// - /// - /// - TemplateNode FindTemplateInTree(TemplateNode anyNode, string alias); - /// /// Saves a /// diff --git a/src/Umbraco.Core/Services/Implement/FileService.cs b/src/Umbraco.Core/Services/Implement/FileService.cs index 4b95a0c1c3..554dacd50d 100644 --- a/src/Umbraco.Core/Services/Implement/FileService.cs +++ b/src/Umbraco.Core/Services/Implement/FileService.cs @@ -503,37 +503,6 @@ namespace Umbraco.Core.Services.Implement } } - /// - /// Returns a template as a template node which can be traversed (parent, children) - /// - /// - /// - [Obsolete("Use GetDescendants instead")] - [EditorBrowsable(EditorBrowsableState.Never)] - public TemplateNode GetTemplateNode(string alias) - { - using (var scope = ScopeProvider.CreateScope(autoComplete: true)) - { - return _templateRepository.GetTemplateNode(alias); - } - } - - /// - /// Given a template node in a tree, this will find the template node with the given alias if it is found in the hierarchy, otherwise null - /// - /// - /// - /// - [Obsolete("Use GetDescendants instead")] - [EditorBrowsable(EditorBrowsableState.Never)] - public TemplateNode FindTemplateInTree(TemplateNode anyNode, string alias) - { - using (var scope = ScopeProvider.CreateScope(autoComplete: true)) - { - return _templateRepository.FindTemplateInTree(anyNode, alias); - } - } - /// /// Saves a /// diff --git a/src/Umbraco.Web/Templates/TemplateUtilities.cs b/src/Umbraco.Web/Templates/TemplateUtilities.cs index 1b76a738af..c14b34c13f 100644 --- a/src/Umbraco.Web/Templates/TemplateUtilities.cs +++ b/src/Umbraco.Web/Templates/TemplateUtilities.cs @@ -22,7 +22,7 @@ namespace Umbraco.Web.Templates { using (UmbracoContext.Current.ForcedPreview(preview)) // force for url provider { - text = ParseInternalLinks(text); + text = ParseInternalLinks(text, UmbracoContext.Current.UrlProvider); } return text; @@ -69,21 +69,6 @@ namespace Umbraco.Web.Templates return text; } - /// - /// Parses the string looking for the {localLink} syntax and updates them to their correct links. - /// - /// - /// - [Obsolete("Use the overload specifying all dependencies instead")] - public static string ParseInternalLinks(string text) - { - //don't attempt to proceed without a context as we cannot lookup urls without one - if (UmbracoContext.Current == null) - return text; - - var urlProvider = UmbracoContext.Current.UrlProvider; - return ParseInternalLinks(text, urlProvider); - } // static compiled regex for faster performance private static readonly Regex LocalLinkPattern = new Regex(@"href=""[/]?(?:\{|\%7B)localLink:([a-zA-Z0-9-://]+)(?:\}|\%7D)", diff --git a/src/Umbraco.Web/UmbracoComponentRenderer.cs b/src/Umbraco.Web/UmbracoComponentRenderer.cs index b23f38fcde..64e8663df6 100644 --- a/src/Umbraco.Web/UmbracoComponentRenderer.cs +++ b/src/Umbraco.Web/UmbracoComponentRenderer.cs @@ -180,7 +180,7 @@ namespace Umbraco.Web _umbracoContext.HttpContext.Response.ContentType = contentType; //Now, we need to ensure that local links are parsed - html = TemplateUtilities.ParseInternalLinks(output.ToString()); + html = TemplateUtilities.ParseInternalLinks(output.ToString(), UmbracoContext.Current.UrlProvider); } } diff --git a/src/Umbraco.Web/umbraco.presentation/default.aspx.cs b/src/Umbraco.Web/umbraco.presentation/default.aspx.cs index 8093b05841..25dcae7a4e 100644 --- a/src/Umbraco.Web/umbraco.presentation/default.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/default.aspx.cs @@ -128,7 +128,7 @@ namespace umbraco string text = sw.ToString(); // filter / parse internal links - although this should be done elsewhere! - text = TemplateUtilities.ParseInternalLinks(text); + text = TemplateUtilities.ParseInternalLinks(text, UmbracoContext.Current.UrlProvider); // filter / add preview banner if (UmbracoContext.Current.InPreviewMode) From 60910efc5397c0259580ff06cdcb09df1b92a1f8 Mon Sep 17 00:00:00 2001 From: Richard Thompson Date: Fri, 27 Jul 2018 14:56:18 +0100 Subject: [PATCH 087/134] U4-10681 Restore option in media recycle bin (#2342) --- src/Umbraco.Core/Constants-Conventions.cs | 10 +++ .../Models/Rdbms/RelationTypeDto.cs | 2 +- .../Migrations/Initial/BaseDataCreation.cs | 3 + .../AddRelationTypeForMediaFolderOnDelete.cs | 38 +++++++++ .../Strategies/RelateOnTrashHandler.cs | 68 ++++++++++++++- src/Umbraco.Core/Umbraco.Core.csproj | 11 +-- .../RelationTypeRepositoryTest.cs | 6 +- .../content/content.restore.controller.js | 14 +-- .../src/views/content/restore.html | 16 ++-- .../views/media/media.restore.controller.js | 85 +++++++++++++++++++ .../src/views/media/restore.html | 26 ++++++ src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 8 ++ .../umbraco/config/lang/en_us.xml | 8 ++ src/Umbraco.Web/Trees/MediaTreeController.cs | 8 +- src/umbraco.cms/Actions/ActionRestore.cs | 2 +- 15 files changed, 278 insertions(+), 27 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/AddRelationTypeForMediaFolderOnDelete.cs create mode 100644 src/Umbraco.Web.UI.Client/src/views/media/media.restore.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/media/restore.html diff --git a/src/Umbraco.Core/Constants-Conventions.cs b/src/Umbraco.Core/Constants-Conventions.cs index b59b7e487e..a19e59f4ef 100644 --- a/src/Umbraco.Core/Constants-Conventions.cs +++ b/src/Umbraco.Core/Constants-Conventions.cs @@ -341,6 +341,16 @@ namespace Umbraco.Core /// ContentType alias for default relation type "Relate Parent Document On Delete". /// public const string RelateParentDocumentOnDeleteAlias = "relateParentDocumentOnDelete"; + + /// + /// ContentType name for default relation type "Relate Parent Media Folder On Delete". + /// + public const string RelateParentMediaFolderOnDeleteName = "Relate Parent Media Folder On Delete"; + + /// + /// ContentType alias for default relation type "Relate Parent Media Folder On Delete". + /// + public const string RelateParentMediaFolderOnDeleteAlias = "relateParentMediaFolderOnDelete"; } } } diff --git a/src/Umbraco.Core/Models/Rdbms/RelationTypeDto.cs b/src/Umbraco.Core/Models/Rdbms/RelationTypeDto.cs index d13ce33520..0c04a1c0be 100644 --- a/src/Umbraco.Core/Models/Rdbms/RelationTypeDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/RelationTypeDto.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.Rdbms [ExplicitColumns] internal class RelationTypeDto { - public const int NodeIdSeed = 3; + public const int NodeIdSeed = 4; [Column("id")] [PrimaryKeyColumn(IdentitySeed = NodeIdSeed)] diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs index da63de3d33..d19e0e0b60 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs @@ -310,6 +310,9 @@ namespace Umbraco.Core.Persistence.Migrations.Initial relationType = new RelationTypeDto { Id = 2, Alias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias, ChildObjectType = new Guid(Constants.ObjectTypes.Document), ParentObjectType = new Guid(Constants.ObjectTypes.Document), Dual = false, Name = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteName }; relationType.UniqueId = (relationType.Alias + "____" + relationType.Name).ToGuid(); _database.Insert("umbracoRelationType", "id", false, relationType); + relationType = new RelationTypeDto { Id = 3, Alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias, ChildObjectType = new Guid(Constants.ObjectTypes.Media), ParentObjectType = new Guid(Constants.ObjectTypes.Media), Dual = false, Name = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName }; + relationType.UniqueId = (relationType.Alias + "____" + relationType.Name).ToGuid(); + _database.Insert("umbracoRelationType", "id", false, relationType); } private void CreateCmsTaskTypeData() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/AddRelationTypeForMediaFolderOnDelete.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/AddRelationTypeForMediaFolderOnDelete.cs new file mode 100644 index 0000000000..9de051e725 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenTwelveZero/AddRelationTypeForMediaFolderOnDelete.cs @@ -0,0 +1,38 @@ +using System; +using Umbraco.Core.Logging; +using Umbraco.Core.Models.Rdbms; +using Umbraco.Core.Persistence.DatabaseAnnotations; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenTwelveZero +{ + [Migration("7.12.0", 0, Constants.System.UmbracoMigrationName)] + public class AddRelationTypeForMediaFolderOnDelete : MigrationBase + { + public AddRelationTypeForMediaFolderOnDelete(ISqlSyntaxProvider sqlSyntax, ILogger logger) + : base(sqlSyntax, logger) + { + } + + public override void Up() + { + var exists = Context.Database.FirstOrDefault("WHERE alias=@alias", new { alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias }); + if (exists == null) + { + var relationTypeDto = new RelationTypeDto + { + Alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias, + Name = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName, + ChildObjectType = Guid.Parse(Constants.ObjectTypes.MediaType), + ParentObjectType = Guid.Parse(Constants.ObjectTypes.MediaType), + Dual = false + }; + + Context.Database.Insert(relationTypeDto); + } + } + + public override void Down() + { } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Strategies/RelateOnTrashHandler.cs b/src/Umbraco.Core/Strategies/RelateOnTrashHandler.cs index 38477aca47..45fe1d76c2 100644 --- a/src/Umbraco.Core/Strategies/RelateOnTrashHandler.cs +++ b/src/Umbraco.Core/Strategies/RelateOnTrashHandler.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using Umbraco.Core.Auditing; using Umbraco.Core.Events; using Umbraco.Core.Models; using Umbraco.Core.Services; @@ -13,6 +12,9 @@ namespace Umbraco.Core.Strategies { ContentService.Moved += ContentService_Moved; ContentService.Trashed += ContentService_Trashed; + + MediaService.Moved += MediaService_Moved; + MediaService.Trashed += MediaService_Trashed; } private void ContentService_Moved(IContentService sender, MoveEventArgs e) @@ -30,10 +32,26 @@ namespace Umbraco.Core.Strategies } } + private void MediaService_Moved(IMediaService sender, MoveEventArgs e) + { + foreach (var item in e.MoveInfoCollection.Where(x => x.OriginalPath.Contains(Constants.System.RecycleBinMedia.ToInvariantString()))) + { + var relationService = ApplicationContext.Current.Services.RelationService; + var relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias; + var relations = relationService.GetByChildId(item.Entity.Id); + + foreach (var relation in relations.Where(x => x.RelationType.Alias.InvariantEquals(relationTypeAlias))) + { + relationService.Delete(relation); + } + } + } + private void ContentService_Trashed(IContentService sender, MoveEventArgs e) { var relationService = ApplicationContext.Current.Services.RelationService; var entityService = ApplicationContext.Current.Services.EntityService; + var textService = ApplicationContext.Current.Services.TextService; var relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias; var relationType = relationService.GetRelationTypeByAlias(relationTypeAlias); @@ -64,7 +82,9 @@ namespace Umbraco.Core.Strategies relationService.Save(relation); ApplicationContext.Current.Services.AuditService.Add(AuditType.Delete, - string.Format("Trashed content with Id: '{0}' related to original parent content with Id: '{1}'", item.Entity.Id, originalParentId), + string.Format(textService.Localize( + "recycleBin/contentTrashed"), + item.Entity.Id, originalParentId), item.Entity.WriterId, item.Entity.Id); } @@ -72,5 +92,49 @@ namespace Umbraco.Core.Strategies } } + + private void MediaService_Trashed(IMediaService sender, MoveEventArgs e) + { + var relationService = ApplicationContext.Current.Services.RelationService; + var entityService = ApplicationContext.Current.Services.EntityService; + var textService = ApplicationContext.Current.Services.TextService; + var relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias; + var relationType = relationService.GetRelationTypeByAlias(relationTypeAlias); + + // check that the relation-type exists, if not, then recreate it + if (relationType == null) + { + var documentObjectType = new Guid(Constants.ObjectTypes.Document); + var relationTypeName = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName; + + relationType = new RelationType(documentObjectType, documentObjectType, relationTypeAlias, relationTypeName); + relationService.Save(relationType); + } + + foreach (var item in e.MoveInfoCollection) + { + var originalPath = item.OriginalPath.ToDelimitedList(); + var originalParentId = originalPath.Count > 2 + ? int.Parse(originalPath[originalPath.Count - 2]) + : Constants.System.Root; + + //before we can create this relation, we need to ensure that the original parent still exists which + //may not be the case if the encompassing transaction also deleted it when this item was moved to the bin + + if (entityService.Exists(originalParentId)) + { + // Add a relation for the item being deleted, so that we can know the original parent for if we need to restore later + var relation = new Relation(originalParentId, item.Entity.Id, relationType); + relationService.Save(relation); + + ApplicationContext.Current.Services.AuditService.Add(AuditType.Delete, + string.Format(textService.Localize( + "recycleBin/mediaTrashed"), + item.Entity.Id, originalParentId), + item.Entity.CreatorId, + item.Entity.Id); + } + } + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 7b8c0fb5b7..7625af7629 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -1,4 +1,4 @@ - + Debug @@ -568,12 +568,13 @@ - - + + + @@ -638,7 +639,7 @@ - + @@ -1688,4 +1689,4 @@ --> - \ No newline at end of file + diff --git a/src/Umbraco.Tests/Persistence/Repositories/RelationTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/RelationTypeRepositoryTest.cs index 9355b90546..bc6c58264e 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/RelationTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/RelationTypeRepositoryTest.cs @@ -139,7 +139,7 @@ namespace Umbraco.Tests.Persistence.Repositories Assert.That(relationTypes, Is.Not.Null); Assert.That(relationTypes.Any(), Is.True); Assert.That(relationTypes.Any(x => x == null), Is.False); - Assert.That(relationTypes.Count(), Is.EqualTo(4)); + Assert.That(relationTypes.Count(), Is.EqualTo(5)); } } @@ -174,7 +174,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Act var exists = repository.Exists(3); - var doesntExist = repository.Exists(5); + var doesntExist = repository.Exists(6); // Assert Assert.That(exists, Is.True); @@ -196,7 +196,7 @@ namespace Umbraco.Tests.Persistence.Repositories int count = repository.Count(query); // Assert - Assert.That(count, Is.EqualTo(4)); + Assert.That(count, Is.EqualTo(5)); } } diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.restore.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.restore.controller.js index c9124bf956..62eaa6fca6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.restore.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/content.restore.controller.js @@ -1,5 +1,5 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController", - function ($scope, relationResource, contentResource, navigationService, appState, treeService) { + function ($scope, relationResource, contentResource, navigationService, appState, treeService, localizationService) { var dialogOptions = $scope.dialogOptions; var node = dialogOptions.currentNode; @@ -12,9 +12,9 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController" if (data.length == 0) { $scope.success = false; $scope.error = { - errorMsg: "Cannot automatically restore this item", + errorMsg: localizationService.localize('recycleBin_itemCannotBeRestored'), data: { - Message: "There is no 'restore' relation found for this node. Use the Move menu item to move it manually." + Message: localizationService.localize('recycleBin_noRestoreRelation') } } return; @@ -32,9 +32,11 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController" // make sure the target item isn't in the recycle bin if($scope.target.path.indexOf("-20") !== -1) { $scope.error = { - errorMsg: "Cannot automatically restore this item", + errorMsg: localizationService.localize('recycleBin_itemCannotBeRestored'), data: { - Message: "The item you want to restore it under (" + $scope.target.name + ") is in the recycle bin. Use the Move menu item to move the item manually." + Message: localizationService.localize('recycleBin_restoreUnderRecycled').then(function (value) { + value.replace('%0%', $scope.target.name); + }) } }; $scope.success = false; @@ -80,4 +82,4 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController" $scope.error = err; }); }; - }); \ No newline at end of file + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/content/restore.html b/src/Umbraco.Web.UI.Client/src/views/content/restore.html index 8564a80bf7..e99e2eb251 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/restore.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/restore.html @@ -2,9 +2,9 @@
      -

      - Restore {{currentNode.name}} under {{target.name}}? -

      +

      + Restore {{currentNode.name}} under {{target.name}}? +

      {{error.errorMsg}}
      @@ -12,15 +12,15 @@
      -

      {{currentNode.name}} was moved underneath {{target.name}}

      - +

      {{currentNode.name}} was moved underneath {{target.name}}

      +
      -
    \ No newline at end of file +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.restore.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.restore.controller.js new file mode 100644 index 0000000000..6ef9232c37 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.restore.controller.js @@ -0,0 +1,85 @@ +angular.module("umbraco").controller("Umbraco.Editors.Media.RestoreController", + function ($scope, relationResource, mediaResource, navigationService, appState, treeService, localizationService) { + var dialogOptions = $scope.dialogOptions; + + var node = dialogOptions.currentNode; + + $scope.error = null; + $scope.success = false; + + relationResource.getByChildId(node.id, "relateParentDocumentOnDelete").then(function (data) { + + if (data.length == 0) { + $scope.success = false; + $scope.error = { + errorMsg: localizationService.localize('recycleBin_itemCannotBeRestored'), + data: { + Message: localizationService.localize('recycleBin_noRestoreRelation') + } + } + return; + } + + $scope.relation = data[0]; + + if ($scope.relation.parentId == -1) { + $scope.target = { id: -1, name: "Root" }; + + } else { + mediaResource.getById($scope.relation.parentId).then(function (data) { + $scope.target = data; + + // make sure the target item isn't in the recycle bin + if ($scope.target.path.indexOf("-20") !== -1) { + $scope.error = { + errorMsg: localizationService.localize('recycleBin_itemCannotBeRestored'), + data: { + Message: localizationService.localize('recycleBin_restoreUnderRecycled').then(function (value) { + value.replace('%0%', $scope.target.name); + }) + } + }; + $scope.success = false; + } + + }, function (err) { + $scope.success = false; + $scope.error = err; + }); + } + + }, function (err) { + $scope.success = false; + $scope.error = err; + }); + + $scope.restore = function () { + // this code was copied from `content.move.controller.js` + mediaResource.move({ parentId: $scope.target.id, id: node.id }) + .then(function (path) { + + $scope.success = true; + + //first we need to remove the node that launched the dialog + treeService.removeNode($scope.currentNode); + + //get the currently edited node (if any) + var activeNode = appState.getTreeState("selectedNode"); + + //we need to do a double sync here: first sync to the moved media item - but don't activate the node, + //then sync to the currenlty edited media item (note: this might not be the media item that was moved!!) + + navigationService.syncTree({ tree: "media", path: path, forceReload: true, activate: false }).then(function (args) { + if (activeNode) { + var activeNodePath = treeService.getPath(activeNode).join(); + //sync to this node now - depending on what was copied this might already be synced but might not be + navigationService.syncTree({ tree: "media", path: activeNodePath, forceReload: false, activate: true }); + } + }); + + }, function (err) { + $scope.success = false; + $scope.error = err; + }); + }; + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/media/restore.html b/src/Umbraco.Web.UI.Client/src/views/media/restore.html new file mode 100644 index 0000000000..17fff154d1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/media/restore.html @@ -0,0 +1,26 @@ +
    +
    + + +

    + Restore {{currentNode.name}} under {{target.name}}? +

    + +
    +
    {{error.errorMsg}}
    +
    {{error.data.Message}}
    +
    + +
    +

    {{currentNode.name}} was moved underneath {{target.name}}

    + +
    + +
    +
    + + +
    diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index eb514a62f7..e9bbbca1aa 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -656,6 +656,7 @@ Submit Type Type to search... + under Up Update Upgrade @@ -2201,4 +2202,11 @@ To manage your website, simply open the Umbraco back office and start adding con characters left + + Trashed content with Id: {0} related to original parent content with Id: {1} + Trashed media with Id: {0} related to original parent media item with Id: {1} + Cannot automatically restore this item + There is no 'restore' relation found for this node. Use the Move menu item to move it manually. + The item you want to restore it under ('%0%') is in the recycle bin. Use the Move menu item to move the item manually. + 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 77dd604bd0..e8e537895a 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -656,6 +656,7 @@ Submit Type Type to search... + under Up Update Upgrade @@ -2193,4 +2194,11 @@ To manage your website, simply open the Umbraco back office and start adding con characters left + + Trashed content with Id: {0} related to original parent content with Id: {1} + Trashed media with Id: {0} related to original parent media item with Id: {1} + Cannot automatically restore this item + There is no 'restore' relation found for this node. Use the Move menu item to move it manually. + The item you want to restore it under ('%0%') is in the recycle bin. Use the Move menu item to move the item manually. + diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs index 99117b3b04..932ced9616 100644 --- a/src/Umbraco.Web/Trees/MediaTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTreeController.cs @@ -140,7 +140,13 @@ namespace Umbraco.Web.Trees //if the media item is in the recycle bin, don't have a default menu, just show the regular menu if (item.Path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Contains(RecycleBinId.ToInvariantString())) { - menu.DefaultMenuAlias = null; + menu.DefaultMenuAlias = null; + menu.Items.Insert(2, new MenuItem(ActionRestore.Instance, ui.Text("actions", ActionRestore.Instance.Alias))); + } + else + { + //set the default to create + menu.DefaultMenuAlias = ActionNew.Instance.Alias; } return menu; diff --git a/src/umbraco.cms/Actions/ActionRestore.cs b/src/umbraco.cms/Actions/ActionRestore.cs index 9b38918fd4..89fb858d6a 100644 --- a/src/umbraco.cms/Actions/ActionRestore.cs +++ b/src/umbraco.cms/Actions/ActionRestore.cs @@ -5,7 +5,7 @@ using umbraco.BasePages; namespace umbraco.BusinessLogic.Actions { /// - /// This action is invoked when the content item is to be restored from the recycle bin + /// This action is invoked when the content/media item is to be restored from the recycle bin /// public class ActionRestore : IAction { From 7559fab5ce2436cff33cbc7b552e639210a94670 Mon Sep 17 00:00:00 2001 From: ashallcross Date: Fri, 27 Jul 2018 15:01:34 +0100 Subject: [PATCH 088/134] Update readme (#2806) --- docs/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 47270a54a3..7e22e4710f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -23,14 +23,14 @@ Umbraco is not only loved by developers, but is a content editors dream. Enjoy i Used by more than 443,000 active websites including Carlsberg, Segway, Amazon and Heinz and **The Official ASP.NET and IIS.NET website from Microsoft** ([https://asp.net](https://asp.net) / [https://iis.net](https://iis.net)), you can be sure that the technology is proven, stable and scales. Backed by the team at Umbraco HQ, and supported by a dedicated community of over 220,000 craftspeople globally, you can trust that Umbraco is a safe choice and is here to stay. -To view more examples, please visit [https://umbraco.com/why-umbraco/#caseStudies](https://umbraco.com/why-umbraco/#caseStudies) +To view more examples, please visit [https://umbraco.com/case-studies-testimonials/](https://umbraco.com/case-studies-testimonials/) ## Why Open Source? As an Open Source platform, Umbraco is more than just a CMS. We are transparent with our roadmap for future versions, our incremental sprint planning notes are publicly accessible and community contributions and packages are available for all to use. ## Trying out Umbraco CMS -[Umbraco Cloud](https://umbraco.com) is the easiest and fastest way to use Umbraco yet with full support for all your custom .NET code and intergrations. You're up and running in less than a minute and your life will be made easier with automated upgrades and a built-in deployment engine. We offer a free 14 day trial, no credit card needed. +[Umbraco Cloud](https://umbraco.com/cloud) is the easiest and fastest way to use Umbraco yet with full support for all your custom .NET code and intergrations. You're up and running in less than a minute and your life will be made easier with automated upgrades and a built-in deployment engine. We offer a free 14 day trial, no credit card needed. If you want to DIY you can [download Umbraco](https://our.umbraco.com/download) either as a ZIP file or via NuGet. It's the same version of Umbraco CMS that powers Umbraco Cloud, but you'll need to find a place to host yourself and handling deployments and upgrades is all down to you. @@ -44,6 +44,6 @@ Umbraco is contribution focused and community driven. If you want to contribute ## Found a bug? -Another way you can contribute to Umbraco is by providing issue reports. For information on how to submit an issue report refer to our [online guide for reporting issues](https://our.umbraco.com/contribute/report-an-issue-or-request-a-feature). +Another way you can contribute to Umbraco is by providing issue reports. For information on how to submit an issue report refer to our [online guide for reporting issues](https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/docs/CONTRIBUTING.md). To view existing issues, please visit [http://issues.umbraco.org](http://issues.umbraco.org). From 8e78c3dfb19e6255566c87a2c1826b642e6e0287 Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 27 Jul 2018 15:51:32 +0100 Subject: [PATCH 089/134] Refactored out some obsolete methods and files. --- .../Configuration/GlobalSettings.cs | 5 +- .../AsynchronousRollingFileAppender.cs | 206 ------------------ src/Umbraco.Core/Models/ContentType.cs | 10 - src/Umbraco.Core/Umbraco.Core.csproj | 1 - src/Umbraco.Tests/Models/ContentTypeTests.cs | 2 +- .../Packaging/PackageExtractionTests.cs | 3 +- .../Services/PackagingServiceTests.cs | 3 +- 7 files changed, 6 insertions(+), 224 deletions(-) delete mode 100644 src/Umbraco.Core/Logging/AsynchronousRollingFileAppender.cs diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index 5f023b8dea..7c274089f7 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -215,10 +215,7 @@ namespace Umbraco.Core.Configuration ConfigurationManager.RefreshSection("appSettings"); } } - - [Obsolete("Use IOHelper.GetRootDirectorySafe() instead")] - public static string FullPathToRoot => IOHelper.GetRootDirectorySafe(); - + /// /// Gets a value indicating whether umbraco is running in [debug mode]. /// diff --git a/src/Umbraco.Core/Logging/AsynchronousRollingFileAppender.cs b/src/Umbraco.Core/Logging/AsynchronousRollingFileAppender.cs deleted file mode 100644 index e14ef92451..0000000000 --- a/src/Umbraco.Core/Logging/AsynchronousRollingFileAppender.cs +++ /dev/null @@ -1,206 +0,0 @@ -using log4net.Core; -using log4net.Util; -using System; -using System.ComponentModel; -using System.Runtime.Remoting.Messaging; -using System.Security.Principal; -using System.Threading; -using System.Threading.Tasks; -using log4net.Appender; - -namespace Umbraco.Core.Logging -{ - /// - /// Based on https://github.com/cjbhaines/Log4Net.Async - /// which is based on code by Chris Haines http://cjbhaines.wordpress.com/2012/02/13/asynchronous-log4net-appenders/ - /// This is an old/deprecated logger and has been superceded by ParallelForwardingAppender which is included in Umbraco and - /// also by AsyncForwardingAppender in the Log4Net.Async library. - /// - [Obsolete("This is superceded by the ParallelForwardingAppender, this will be removed in v8, do not use this")] - [EditorBrowsable(EditorBrowsableState.Never)] - public class AsynchronousRollingFileAppender : RollingFileAppender - { - private RingBuffer pendingAppends; - private readonly ManualResetEvent manualResetEvent; - private bool shuttingDown; - private bool hasFinished; - private bool forceStop; - private bool logBufferOverflow; - private int bufferOverflowCounter; - private DateTime lastLoggedBufferOverflow; - private int queueSizeLimit = 1000; - public int QueueSizeLimit - { - get - { - return queueSizeLimit; - } - set - { - queueSizeLimit = value; - } - } - - public AsynchronousRollingFileAppender() - { - manualResetEvent = new ManualResetEvent(false); - } - - public override void ActivateOptions() - { - base.ActivateOptions(); - pendingAppends = new RingBuffer(QueueSizeLimit); - pendingAppends.BufferOverflow += OnBufferOverflow; - StartAppendTask(); - } - - protected override void Append(LoggingEvent[] loggingEvents) - { - Array.ForEach(loggingEvents, Append); - } - - protected override void Append(LoggingEvent loggingEvent) - { - if (FilterEvent(loggingEvent)) - { - pendingAppends.Enqueue(loggingEvent); - } - } - - protected override void OnClose() - { - shuttingDown = true; - manualResetEvent.WaitOne(TimeSpan.FromSeconds(5)); - - if (!hasFinished) - { - forceStop = true; - base.Append(new LoggingEvent(new LoggingEventData - { - Level = Level.Error, - Message = "Unable to clear out the AsyncRollingFileAppender buffer in the allotted time, forcing a shutdown", - TimeStamp = DateTime.UtcNow, - Identity = "", - ExceptionString = "", - UserName = WindowsIdentity.GetCurrent() != null ? WindowsIdentity.GetCurrent().Name : "", - Domain = AppDomain.CurrentDomain.FriendlyName, - ThreadName = Thread.CurrentThread.ManagedThreadId.ToString(), - LocationInfo = new LocationInfo(this.GetType().Name, "OnClose", "AsyncRollingFileAppender.cs", "75"), - LoggerName = this.GetType().FullName, - Properties = new PropertiesDictionary(), - }) - ); - } - - base.OnClose(); - } - - private void StartAppendTask() - { - if (!shuttingDown) - { - Task appendTask = new Task(AppendLoggingEvents, TaskCreationOptions.LongRunning); - appendTask.LogErrors(LogAppenderError).ContinueWith(x => StartAppendTask()).LogErrors(LogAppenderError); - appendTask.Start(); - } - } - - private void LogAppenderError(string logMessage, Exception exception) - { - base.Append(new LoggingEvent(new LoggingEventData - { - Level = Level.Error, - Message = "Appender exception: " + logMessage, - TimeStamp = DateTime.UtcNow, - Identity = "", - ExceptionString = exception.ToString(), - UserName = WindowsIdentity.GetCurrent() != null ? WindowsIdentity.GetCurrent().Name : "", - Domain = AppDomain.CurrentDomain.FriendlyName, - ThreadName = Thread.CurrentThread.ManagedThreadId.ToString(), - LocationInfo = new LocationInfo(this.GetType().Name, "LogAppenderError", "AsyncRollingFileAppender.cs", "152"), - LoggerName = this.GetType().FullName, - Properties = new PropertiesDictionary(), - })); - } - - private void AppendLoggingEvents() - { - LoggingEvent loggingEventToAppend; - while (!shuttingDown) - { - if (logBufferOverflow) - { - LogBufferOverflowError(); - logBufferOverflow = false; - bufferOverflowCounter = 0; - lastLoggedBufferOverflow = DateTime.UtcNow; - } - - while (!pendingAppends.TryDequeue(out loggingEventToAppend)) - { - Thread.Sleep(10); - if (shuttingDown) - { - break; - } - } - if (loggingEventToAppend == null) - { - continue; - } - - try - { - base.Append(loggingEventToAppend); - } - catch - { - } - } - - while (pendingAppends.TryDequeue(out loggingEventToAppend) && !forceStop) - { - try - { - base.Append(loggingEventToAppend); - } - catch - { - } - } - hasFinished = true; - manualResetEvent.Set(); - } - - private void LogBufferOverflowError() - { - base.Append(new LoggingEvent(new LoggingEventData - { - Level = Level.Error, - Message = string.Format("Buffer overflow. {0} logging events have been lost in the last 30 seconds. [QueueSizeLimit: {1}]", bufferOverflowCounter, QueueSizeLimit), - TimeStamp = DateTime.UtcNow, - Identity = "", - ExceptionString = "", - UserName = WindowsIdentity.GetCurrent() != null ? WindowsIdentity.GetCurrent().Name : "", - Domain = AppDomain.CurrentDomain.FriendlyName, - ThreadName = Thread.CurrentThread.ManagedThreadId.ToString(), - LocationInfo = new LocationInfo(this.GetType().Name, "LogBufferOverflowError", "AsyncRollingFileAppender.cs", "152"), - LoggerName = this.GetType().FullName, - Properties = new PropertiesDictionary(), - })); - } - - private void OnBufferOverflow(object sender, EventArgs eventArgs) - { - bufferOverflowCounter++; - if (logBufferOverflow == false) - { - if (lastLoggedBufferOverflow < DateTime.UtcNow.AddSeconds(-30)) - { - logBufferOverflow = true; - } - } - } - } - -} diff --git a/src/Umbraco.Core/Models/ContentType.cs b/src/Umbraco.Core/Models/ContentType.cs index 196c68b23c..ff647dc189 100644 --- a/src/Umbraco.Core/Models/ContentType.cs +++ b/src/Umbraco.Core/Models/ContentType.cs @@ -136,15 +136,5 @@ namespace Umbraco.Core.Models return result; } - - /// - /// Creates a deep clone of the current entity with its identity/alias and it's property identities reset - /// - /// - [Obsolete("Use DeepCloneWithResetIdentities instead")] - public IContentType Clone(string alias) - { - return DeepCloneWithResetIdentities(alias); - } } } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 3954267118..321458b05f 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -543,7 +543,6 @@ - diff --git a/src/Umbraco.Tests/Models/ContentTypeTests.cs b/src/Umbraco.Tests/Models/ContentTypeTests.cs index c63853940f..a0e9a370da 100644 --- a/src/Umbraco.Tests/Models/ContentTypeTests.cs +++ b/src/Umbraco.Tests/Models/ContentTypeTests.cs @@ -72,7 +72,7 @@ namespace Umbraco.Tests.Models //ensure that nothing is marked as dirty contentType.ResetDirtyProperties(false); - var clone = (ContentType)contentType.Clone("newAlias"); + var clone = (ContentType)contentType.DeepCloneWithResetIdentities("newAlias"); Assert.AreEqual("newAlias", clone.Alias); Assert.AreNotEqual("newAlias", contentType.Alias); diff --git a/src/Umbraco.Tests/Packaging/PackageExtractionTests.cs b/src/Umbraco.Tests/Packaging/PackageExtractionTests.cs index 118d57ab2a..5416162ed2 100644 --- a/src/Umbraco.Tests/Packaging/PackageExtractionTests.cs +++ b/src/Umbraco.Tests/Packaging/PackageExtractionTests.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using NUnit.Framework; +using Umbraco.Core.IO; using Umbraco.Core.Packaging; namespace Umbraco.Tests.Packaging @@ -14,7 +15,7 @@ namespace Umbraco.Tests.Packaging private static string GetTestPackagePath(string packageName) { const string testPackagesDirName = "Packaging\\Packages"; - string path = Path.Combine(Core.Configuration.GlobalSettings.FullPathToRoot, testPackagesDirName, packageName); + string path = Path.Combine(IOHelper.GetRootDirectorySafe(), testPackagesDirName, packageName); return path; } diff --git a/src/Umbraco.Tests/Services/PackagingServiceTests.cs b/src/Umbraco.Tests/Services/PackagingServiceTests.cs index 829365ae7f..87225c1288 100644 --- a/src/Umbraco.Tests/Services/PackagingServiceTests.cs +++ b/src/Umbraco.Tests/Services/PackagingServiceTests.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Xml.Linq; using NUnit.Framework; +using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Models.Packaging; using Umbraco.Core.Services; @@ -76,7 +77,7 @@ namespace Umbraco.Tests.Services private static string GetTestPackagePath(string packageName) { const string testPackagesDirName = "Packaging\\Packages"; - string path = Path.Combine(Core.Configuration.GlobalSettings.FullPathToRoot, testPackagesDirName, packageName); + string path = Path.Combine(IOHelper.GetRootDirectorySafe(), testPackagesDirName, packageName); return path; } From 7baca85f6a12e2ade4608dd8aa5738b7ffc39d42 Mon Sep 17 00:00:00 2001 From: Imran Haider Date: Fri, 27 Jul 2018 16:08:38 +0100 Subject: [PATCH 090/134] Update ourumbraco references to https --- .../UmbracoSettings/HelpElement.cs | 2 +- .../Packaging/Models/PackageAction.cs | 2 +- src/Umbraco.Core/Sync/ApplicationUrlHelper.cs | 2 +- .../umbracoSettings.minimal.config | 36 +++++++++--------- .../SqlScripts/SqlCe-SchemaAndData-4110.sql | Bin 422840 -> 422888 bytes .../Importing/ImportResources.Designer.cs | 4 +- .../Importing/StandardMvc-Package.xml | 4 +- .../Importing/TemplateOnly-Package.xml | 2 +- .../TemplateOnly-Updated-Package.xml | 2 +- .../Services/Importing/uBlogsy-Package.xml | 2 +- .../Services/PerformanceTests.cs | 2 +- .../src/common/services/help.service.js | 2 +- .../installer/steps/permissionsreport.html | 2 +- .../src/installer/steps/starterkit.html | 2 +- .../src/views/common/dialogs/help.html | 2 +- .../src/views/common/drawers/help/help.html | 2 +- .../src/views/common/overlays/help/help.html | 2 +- .../developer/developerdashboardintro.html | 6 +-- .../members/membersdashboardintro.html | 2 +- .../Properties/Settings.Designer.cs | 2 +- .../Properties/Settings.settings | 2 +- src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml | 4 +- .../Umbraco/config/lang/zh_tw.xml | 4 +- .../config/umbracoSettings.Release.config | 2 +- src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/de.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 4 +- .../umbraco/config/lang/en_us.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/es.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/fr.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/he.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/it.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/ja.xml | 2 +- src/Umbraco.Web.UI/umbraco/config/lang/ko.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/nl.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/pl.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/pt.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/ru.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/sv.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/tr.xml | 4 +- src/Umbraco.Web.UI/umbraco/config/lang/zh.xml | 4 +- .../Tree/jquery.tree.contextmenu.js | 2 +- src/Umbraco.Web.UI/web.Template.config | 2 +- src/Umbraco.Web/Install/InstallHelper.cs | 2 +- .../EnsurePublishedContentRequestAttribute.cs | 2 +- src/Umbraco.Web/Properties/Settings.settings | 2 +- .../Properties/Settings1.Designer.cs | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 4 +- .../org.umbraco.our/Reference.map | 4 +- .../org.umbraco.our/repository.disco | 6 +-- .../org.umbraco.our/repository.wsdl | 8 ++-- src/Umbraco.Web/app.config | 2 +- .../developer/Packages/editPackage.aspx | 2 +- .../umbraco/uQuery/DocumentExtensions.cs | 4 +- .../umbraco/uQuery/NodeExtensions.cs | 8 ++-- .../umbraco/uQuery/uQuery-Nodes.cs | 2 +- .../IntegerDataTypeModel.cs | 2 +- 57 files changed, 106 insertions(+), 106 deletions(-) diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/HelpElement.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/HelpElement.cs index eb1e452100..6224150c51 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/HelpElement.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/HelpElement.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings [Obsolete("This is no longer used and will be removed in future versions")] internal class HelpElement : ConfigurationElement, IHelpSection { - [ConfigurationProperty("defaultUrl", DefaultValue = "http://our.umbraco.org/wiki/umbraco-help/{0}/{1}")] + [ConfigurationProperty("defaultUrl", DefaultValue = "https://our.umbraco.org/wiki/umbraco-help/{0}/{1}")] public string DefaultUrl { get { return (string) base["defaultUrl"]; } diff --git a/src/Umbraco.Core/Packaging/Models/PackageAction.cs b/src/Umbraco.Core/Packaging/Models/PackageAction.cs index 58f7de8078..a5fcc75220 100644 --- a/src/Umbraco.Core/Packaging/Models/PackageAction.cs +++ b/src/Umbraco.Core/Packaging/Models/PackageAction.cs @@ -27,7 +27,7 @@ namespace Umbraco.Core.Packaging.Models set { _runAt = value; } } - public bool Undo //NOTE: Should thid default to "False"? but the documentation says default "True" (http://our.umbraco.org/wiki/reference/packaging/package-actions) + public bool Undo //NOTE: Should thid default to "False"? but the documentation says default "True" (https://our.umbraco.org/wiki/reference/packaging/package-actions) { get { return _undo ?? true; } set { _undo = value; } diff --git a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs index 57520a3754..bee4351577 100644 --- a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs +++ b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs @@ -156,7 +156,7 @@ namespace Umbraco.Core.Sync // otherwise, // if non-standard ports used, // user may need to set umbracoApplicationUrl manually per - // http://our.umbraco.org/documentation/Using-Umbraco/Config-files/umbracoSettings/#ScheduledTasks + // https://our.umbraco.org/documentation/Using-Umbraco/Config-files/umbracoSettings/#ScheduledTasks var port = (request.IsSecureConnection == false && GlobalSettings.UseSSL == false) || (request.IsSecureConnection && GlobalSettings.UseSSL) ? ":" + request.ServerVariables["SERVER_PORT"] diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.minimal.config b/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.minimal.config index b6ea54d75e..f105e17463 100644 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.minimal.config +++ b/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.minimal.config @@ -3,27 +3,27 @@ - + - + - + - + 1 - + robot@umbraco.dk @@ -31,42 +31,42 @@ - - - + Mvc - + - + - + - + - + - + - + - + - + diff --git a/src/Umbraco.Tests/Migrations/SqlScripts/SqlCe-SchemaAndData-4110.sql b/src/Umbraco.Tests/Migrations/SqlScripts/SqlCe-SchemaAndData-4110.sql index ee157be2a7727816291ced4cab1a95fadc67e061..23a8acfd31d0ce6c35c48652dc43e4116f7bf9ed 100644 GIT binary patch delta 345 zcmdn-T=KlQW>|oB^zGfB^4-;eY_K!j=$;>dpJz^|dfPx?us?+CX zvgmE^Sj^-x1Ej2jITb7;#8SL{!x7edP-WTM1^Ss6AnR$^E^?Dejd6Q~8}lqD5_N`5 zV%DmIIfghFP6xU$V!M|&f=z{$opEr-=<`>`{u HpOygt5gLcD delta 402 zcmaFyTyn>A$%YojEle)6rYB@DvrVrMV@cc2BFMtQ1mVwcWLB6yp_|!fdxJ2`2Z-Qy zpdvA5i2RC77N6}C7BhLwfU8g0p4Z9zixJLO*bdaM1yR2pXdVkf>%8qblbF>Qw`aI9 z&vJrmAk_e^I*3+s+&&%X_K59PQY?$yNVUHm==bd_GFhV{NYx3{#d3pj`T|ZizUcy` RtWMJ;SXs9JI>Y*I835nFhB5#E diff --git a/src/Umbraco.Tests/Services/Importing/ImportResources.Designer.cs b/src/Umbraco.Tests/Services/Importing/ImportResources.Designer.cs index c640d21aa7..46dada5a9b 100644 --- a/src/Umbraco.Tests/Services/Importing/ImportResources.Designer.cs +++ b/src/Umbraco.Tests/Services/Importing/ImportResources.Designer.cs @@ -313,7 +313,7 @@ namespace Umbraco.Tests.Services.Importing { /// <name>Template-Update</name> /// <version>0.1</version> /// <license url="http://www.opensource.org/licenses/mit-license.php">MIT license</license> - /// <url>http://our.umbraco.org/projects</url> + /// <url>https://our.umbraco.org/projects</url> /// <requirements> /// <major>3</major> /// <minor>0</minor> @@ -339,7 +339,7 @@ namespace Umbraco.Tests.Services.Importing { /// <name>Template-Update</name> /// <version>0.1</version> /// <license url="http://www.opensource.org/licenses/mit-license.php">MIT license</license> - /// <url>http://our.umbraco.org/projects</url> + /// <url>https://our.umbraco.org/projects</url> /// <requirements> /// <major>3</major> /// <minor>0</minor> diff --git a/src/Umbraco.Tests/Services/Importing/StandardMvc-Package.xml b/src/Umbraco.Tests/Services/Importing/StandardMvc-Package.xml index 82cbcc5d84..e6e4708a2e 100644 --- a/src/Umbraco.Tests/Services/Importing/StandardMvc-Package.xml +++ b/src/Umbraco.Tests/Services/Importing/StandardMvc-Package.xml @@ -177,7 +177,7 @@ StandardWebsiteMVC 2.0 MIT license - http://our.umbraco.org/projects/starter-kits/standard-website-mvc + https://our.umbraco.org/projects/starter-kits/standard-website-mvc 3 0 @@ -218,7 +218,7 @@ Google Maps - A map macro that you can use within Rich Text Areas Contact Us -

    Contact Us on TwitterWe'd love to hear how this package has helped you and how it can be improved. Get in touch on the project website or via twitter

    ]]> +

    Contact Us on TwitterWe'd love to hear how this package has helped you and how it can be improved. Get in touch on the project website or via twitter

    ]]>
    Standard Website MVC, Company Address, Glasgow, Postcode
    diff --git a/src/Umbraco.Tests/Services/Importing/TemplateOnly-Package.xml b/src/Umbraco.Tests/Services/Importing/TemplateOnly-Package.xml index 1f29ffb806..675a5f8483 100644 --- a/src/Umbraco.Tests/Services/Importing/TemplateOnly-Package.xml +++ b/src/Umbraco.Tests/Services/Importing/TemplateOnly-Package.xml @@ -6,7 +6,7 @@ Template-Update 0.1 MIT license - http://our.umbraco.org/projects + https://our.umbraco.org/projects 3 0 diff --git a/src/Umbraco.Tests/Services/Importing/TemplateOnly-Updated-Package.xml b/src/Umbraco.Tests/Services/Importing/TemplateOnly-Updated-Package.xml index 1225b36fa2..1cbd9bb3f3 100644 --- a/src/Umbraco.Tests/Services/Importing/TemplateOnly-Updated-Package.xml +++ b/src/Umbraco.Tests/Services/Importing/TemplateOnly-Updated-Package.xml @@ -6,7 +6,7 @@ Template-Update 0.1 MIT license - http://our.umbraco.org/projects + https://our.umbraco.org/projects 3 0 diff --git a/src/Umbraco.Tests/Services/Importing/uBlogsy-Package.xml b/src/Umbraco.Tests/Services/Importing/uBlogsy-Package.xml index 98e12465f5..86addb351f 100644 --- a/src/Umbraco.Tests/Services/Importing/uBlogsy-Package.xml +++ b/src/Umbraco.Tests/Services/Importing/uBlogsy-Package.xml @@ -332,7 +332,7 @@ uBlogsy 3.0 MIT license - http://our.umbraco.org/projects/starter-kits/ublogsy + https://our.umbraco.org/projects/starter-kits/ublogsy 3 0 diff --git a/src/Umbraco.Tests/Services/PerformanceTests.cs b/src/Umbraco.Tests/Services/PerformanceTests.cs index 69f39392d6..39a3f00bed 100644 --- a/src/Umbraco.Tests/Services/PerformanceTests.cs +++ b/src/Umbraco.Tests/Services/PerformanceTests.cs @@ -314,7 +314,7 @@ namespace Umbraco.Tests.Services Umbraco Development

    UmbracoUmbraco the the leading ASP.NET open source CMS, under pinning over 150,000 websites. Our Certified Developers are experts in developing high performance and feature rich websites.

    ]]>
    Contact Us -

    Contact Us on TwitterWe'd love to hear how this package has helped you and how it can be improved. Get in touch on the project website or via twitter

    ]]>
    +

    Contact Us on TwitterWe'd love to hear how this package has helped you and how it can be improved. Get in touch on the project website or via twitter

    ]]>
    Standard Website MVC, Company Address, Glasgow, Postcode
    Copyright &copy; 2012 Your Company diff --git a/src/Umbraco.Web.UI.Client/src/common/services/help.service.js b/src/Umbraco.Web.UI.Client/src/common/services/help.service.js index 77621eee9c..bad1fa4e49 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/help.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/help.service.js @@ -2,7 +2,7 @@ angular.module('umbraco.services') .factory('helpService', function ($http, $q, umbRequestHelper) { var helpTopics = {}; - var defaultUrl = "http://our.umbraco.org/rss/help"; + var defaultUrl = "https://our.umbraco.org/rss/help"; var tvUrl = "http://umbraco.tv/feeds/help"; function getCachedHelp(url){ diff --git a/src/Umbraco.Web.UI.Client/src/installer/steps/permissionsreport.html b/src/Umbraco.Web.UI.Client/src/installer/steps/permissionsreport.html index 3ced6ed678..266f360394 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/steps/permissionsreport.html +++ b/src/Umbraco.Web.UI.Client/src/installer/steps/permissionsreport.html @@ -3,7 +3,7 @@

    In order to run umbraco, you'll need to update your permission settings. Detailed information about the correct file & folder permissions for Umbraco can be found - here. + here.

    The following report list the permissions that are currently failing. Once the permissions are fixed press the 'Go back' button to restart the installation. diff --git a/src/Umbraco.Web.UI.Client/src/installer/steps/starterkit.html b/src/Umbraco.Web.UI.Client/src/installer/steps/starterkit.html index 0b9e22a0f3..2f76de5525 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/steps/starterkit.html +++ b/src/Umbraco.Web.UI.Client/src/installer/steps/starterkit.html @@ -12,7 +12,7 @@

  • Loading... - {{pck.name}} + {{pck.name}}
  • diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.html index b9428fb242..a6d3827343 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.html @@ -22,7 +22,7 @@