From 7aeea96e2353414eb69ee63f831be80fd5b6d73b Mon Sep 17 00:00:00 2001 From: Tim Geyssens Date: Fri, 11 Nov 2016 11:45:25 +0100 Subject: [PATCH 01/70] 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 02/70] 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 03/70] 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 04/70] 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 05/70] 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 06/70] 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 07/70] 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 08/70] 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 09/70] 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 10/70] 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 11/70] 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 12/70] 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 13/70] 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 c0b094f2e8640c44bccebfe453fc18484831a3ec Mon Sep 17 00:00:00 2001 From: Russell Date: Wed, 27 Jun 2018 10:06:45 +1200 Subject: [PATCH 14/70] 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 15/70] 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 16/70] 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 17/70] 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 18/70] 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 19/70] 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 20/70] 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 21/70] 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 22/70] 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 23/70] 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 24/70] 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 25/70] 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 26/70] 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 27/70] 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 28/70] 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 29/70] 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 30/70] 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 31/70] 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 32/70] 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 33/70] 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 34/70] 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 35/70] 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 36/70] =?UTF-8?q?U4-11152=20Add=20visual=20indicator=20to?= =?UTF-8?q?=20trashed=20media=20items=20in=20the=20media=20pic=E2=80=A6=20?= =?UTF-8?q?(#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 39/70] 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 40/70] 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 41/70] 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 42/70] 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 43/70] 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 44/70] 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 45/70] 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 46/70] 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 47/70] =?UTF-8?q?Cleaning=20up=20the=20mess=20I=20made=20?= =?UTF-8?q?=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 48/70] 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 49/70] 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 50/70] 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 51/70] 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 52/70] 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 53/70] 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 0f3a8bff5d9ed6422113e1c4be8de9522c6fa281 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Thu, 26 Jul 2018 11:17:53 +0200 Subject: [PATCH 54/70] 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 99181d5bf45add5400dbc33ea57caf293fb38ec6 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Thu, 26 Jul 2018 11:23:24 +0200 Subject: [PATCH 55/70] 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 56/70] 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 57/70] 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 58/70] 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 59/70] 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 60/70] 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 61/70] 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 62/70] 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 63/70] 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 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 64/70] 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 65/70] 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 bd3f7ffcd463943a9e35368ebffea4ec590c1c22 Mon Sep 17 00:00:00 2001 From: BatJan Date: Fri, 27 Jul 2018 14:35:04 +0200 Subject: [PATCH 66/70] 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 8c1f236e3f384b34ed0ff1543fb6670cb2fe0587 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 27 Jul 2018 15:08:48 +0200 Subject: [PATCH 67/70] 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 68/70] 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 60910efc5397c0259580ff06cdcb09df1b92a1f8 Mon Sep 17 00:00:00 2001 From: Richard Thompson Date: Fri, 27 Jul 2018 14:56:18 +0100 Subject: [PATCH 69/70] 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 70/70] 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).