From be2ed0e8da2ffe1d9280d6c26b6aaf8e8fd614fd Mon Sep 17 00:00:00 2001 From: "skg@novicell.dk" Date: Thu, 1 Mar 2018 20:17:38 +0100 Subject: [PATCH 001/111] Added a generic TableExists-method --- src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs b/src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs index 944d5a8a74..f03e751427 100644 --- a/src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs +++ b/src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs @@ -31,6 +31,13 @@ namespace Umbraco.Core.Persistence return _syntaxProvider.DoesTableExist(_db, tableName); } + public bool TableExist() + { + var poco = Database.PocoData.ForType(typeof(T)); + var tableName = poco.TableInfo.TableName; + return TableExist(tableName); + } + internal void UninstallDatabaseSchema() { var creation = new DatabaseSchemaCreation(_db, _logger, _syntaxProvider); @@ -194,4 +201,4 @@ namespace Umbraco.Core.Persistence _db.Execute(sql); } } -} \ No newline at end of file +} From 20216df8cfce3e656b59c615cf95ddc302f48d63 Mon Sep 17 00:00:00 2001 From: Rune Hem Strand Date: Fri, 2 Mar 2018 17:49:02 +0100 Subject: [PATCH 002/111] Add check to avoid cicular template reference --- .../src/views/templates/edit.controller.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/templates/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/templates/edit.controller.js index 5d2129668e..8b03b90a67 100644 --- a/src/Umbraco.Web.UI.Client/src/views/templates/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/templates/edit.controller.js @@ -516,9 +516,13 @@ var availableMasterTemplates = []; // filter out the current template and the selected master template - angular.forEach(vm.templates, function(template){ - if(template.alias !== vm.template.alias && template.alias !== vm.template.masterTemplateAlias) { - availableMasterTemplates.push(template); + angular.forEach(vm.templates, function (template) { + if (template.alias !== vm.template.alias && template.alias !== vm.template.masterTemplateAlias) { + var templatePathArray = template.path.split(','); + // filter descendant templates of current template + if (templatePathArray.indexOf(String(vm.template.id)) === -1) { + availableMasterTemplates.push(template); + } } }); From b962d2a9d31263249c08734cc13e80c681ff4741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Vanbrabandt?= Date: Tue, 27 Mar 2018 15:55:28 +0200 Subject: [PATCH 003/111] Update NL.xml with missing translations --- src/Umbraco.Web.UI/umbraco/config/lang/nl.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml b/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml index fd49f9764b..2265ba590a 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml @@ -172,6 +172,13 @@ Doel Dit betekend de volgende tijd op de server: Wat houd dit in?]]> + Ben je er zeker van dat je dit item wilt verwijderen? + Eigenschap %0% gebruikt editor %1% welke niet wordt ondersteund door Nested Content. + Voeg nog een tekstvak toe + Verwijder dit tekstvak + Content root + Deze waarde is verborgen. Indien u toegang nodig heeft om deze waarde te bekijken, contacteer dan uw website administrator. + Deze waarde is verborgen Klik om te uploaden @@ -1146,7 +1153,12 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je die gebruik maken van deze editor zullen geupdate worden met deze nieuwe instellingen Lid kan bewerken + Toestaan dat deze eigenschap kan worden gewijzigd door het lid op zijn profiel pagina. + Omvat gevoelige gegevens + Verberg deze eigenschap voor de content editor dat geen toegang heeft tot het bekijken van gevoelige informatie. Toon in het profiel van leden + Toelaten dat deze eigenschap wordt getoond op de profiel pagina van het lid. + tab heeft geen sorteervolgorde From b0ab408fda136677e93413307ff1e0db0ad88c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Vanbrabandt?= Date: Tue, 27 Mar 2018 17:19:24 +0200 Subject: [PATCH 004/111] Update NL.xml Set die instead of dat --- src/Umbraco.Web.UI/umbraco/config/lang/nl.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml b/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml index 2265ba590a..1e03f6f76c 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml @@ -1155,7 +1155,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Lid kan bewerken Toestaan dat deze eigenschap kan worden gewijzigd door het lid op zijn profiel pagina. Omvat gevoelige gegevens - Verberg deze eigenschap voor de content editor dat geen toegang heeft tot het bekijken van gevoelige informatie. + Verberg deze eigenschap voor de content editor die geen toegang heeft tot het bekijken van gevoelige informatie. Toon in het profiel van leden Toelaten dat deze eigenschap wordt getoond op de profiel pagina van het lid. From a623e4034c75106d991e006aaa5b85e0d7c9edbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Gregersen?= Date: Wed, 28 Mar 2018 11:00:35 +0200 Subject: [PATCH 005/111] Updated documentation + default values for getPagedDescendants Changed type in example, from unknown "Content" to known "Document". Also changed the default values to show the first page, with a 100 results, instead the 100th page with 1 result. --- .../src/common/resources/entity.resource.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js index 5dd353d9e0..72f8ad5539 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js @@ -406,7 +406,7 @@ function entityResource($q, $http, umbRequestHelper) { * * ##usage *
-          * entityResource.getPagedDescendants(1234, "Content", {pageSize: 10, pageNumber: 2})
+          * entityResource.getPagedDescendants(1234, "Document", {pageSize: 10, pageNumber: 2})
           *    .then(function(contentArray) {
           *        var children = contentArray; 
           *        alert('they are here!');
@@ -416,8 +416,8 @@ function entityResource($q, $http, umbRequestHelper) {
           * @param {Int} parentid id of content item to return descendants of
           * @param {string} type Object type name
           * @param {Object} options optional options object
-          * @param {Int} options.pageSize if paging data, number of nodes per page, default = 1
-          * @param {Int} options.pageNumber if paging data, current page index, default = 100
+          * @param {Int} options.pageSize if paging data, number of nodes per page, default = 100
+          * @param {Int} options.pageNumber if paging data, current page index, default = 1
           * @param {String} options.filter if provided, query will only return those with names matching the filter
           * @param {String} options.orderDirection can be `Ascending` or `Descending` - Default: `Ascending`
           * @param {String} options.orderBy property to order items by, default: `SortOrder`
@@ -427,8 +427,8 @@ function entityResource($q, $http, umbRequestHelper) {
         getPagedDescendants: function (parentId, type, options) {
 
             var defaults = {
-                pageSize: 1,
-                pageNumber: 100,
+                pageSize: 100,
+                pageNumber: 1,
                 filter: '',
                 orderDirection: "Ascending",
                 orderBy: "SortOrder"

From 23612d7599e9f83b758700d73d9a42dd50f51ec9 Mon Sep 17 00:00:00 2001
From: leekelleher 
Date: Mon, 19 Mar 2018 13:25:32 +0000
Subject: [PATCH 006/111] U4-9668 RelationService - Relates entities by ID and
 a relationType + Alias

Currently you need to supply both parent & child entities to create a new relation.
When the underlying code requires the entity IDs (int).

This patch adds methods to accept the int IDs.
http://issues.umbraco.org/issue/U4-9668

This patch also de-duplicates the logic from `Relate(IUmbracoEntity, IUmbracoEntity, string)`,
as it was the same as the method body of `Relate(IUmbracoEntity, IUmbracoEntity, IRelationType)`.
---
 src/Umbraco.Core/Services/IRelationService.cs | 18 ++++
 src/Umbraco.Core/Services/RelationService.cs  | 86 +++++++++++--------
 2 files changed, 67 insertions(+), 37 deletions(-)

diff --git a/src/Umbraco.Core/Services/IRelationService.cs b/src/Umbraco.Core/Services/IRelationService.cs
index 5fb1f3c8cc..6006a6b7c3 100644
--- a/src/Umbraco.Core/Services/IRelationService.cs
+++ b/src/Umbraco.Core/Services/IRelationService.cs
@@ -189,6 +189,15 @@ namespace Umbraco.Core.Services
             IEnumerable relations,
             bool loadBaseType = false);
 
+        /// 
+        /// Relates two objects by their entity Ids.
+        /// 
+        /// Id of the parent
+        /// Id of the child
+        /// The type of relation to create
+        /// The created 
+        IRelation Relate(int parentId, int childId, IRelationType relationType);
+
         /// 
         /// Relates two objects that are based on the  interface.
         /// 
@@ -198,6 +207,15 @@ namespace Umbraco.Core.Services
         /// The created 
         IRelation Relate(IUmbracoEntity parent, IUmbracoEntity child, IRelationType relationType);
 
+        /// 
+        /// Relates two objects by their entity Ids.
+        /// 
+        /// Id of the parent
+        /// Id of the child
+        /// Alias of the type of relation to create
+        /// The created 
+        IRelation Relate(int parentId, int childId, string relationTypeAlias);
+
         /// 
         /// Relates two objects that are based on the  interface.
         /// 
diff --git a/src/Umbraco.Core/Services/RelationService.cs b/src/Umbraco.Core/Services/RelationService.cs
index b05e8e2391..ccf86d425d 100644
--- a/src/Umbraco.Core/Services/RelationService.cs
+++ b/src/Umbraco.Core/Services/RelationService.cs
@@ -394,6 +394,39 @@ namespace Umbraco.Core.Services
             }
         }
 
+        /// 
+        /// Relates two objects by their entity Ids.
+        /// 
+        /// Id of the parent
+        /// Id of the child
+        /// The type of relation to create
+        /// The created 
+        public IRelation Relate(int parentId, int childId, IRelationType relationType)
+        {
+            // Ensure that the RelationType has an indentity before using it to relate two entities
+            if (relationType.HasIdentity == false)
+                Save(relationType);
+
+            var relation = new Relation(parentId, childId, relationType);
+
+            using (var uow = UowProvider.GetUnitOfWork())
+            {
+                var saveEventArgs = new SaveEventArgs(relation);
+                if (uow.Events.DispatchCancelable(SavingRelation, this, saveEventArgs))
+                {
+                    uow.Commit();
+                    return relation;
+                }
+
+                var repository = RepositoryFactory.CreateRelationRepository(uow);
+                repository.AddOrUpdate(relation);
+                uow.Commit();
+                saveEventArgs.CanCancel = false;
+                uow.Events.Dispatch(SavedRelation, this, saveEventArgs);
+                return relation;
+            }
+        }
+
         /// 
         /// Relates two objects that are based on the  interface.
         /// 
@@ -403,28 +436,23 @@ namespace Umbraco.Core.Services
         /// The created 
         public IRelation Relate(IUmbracoEntity parent, IUmbracoEntity child, IRelationType relationType)
         {
-            //Ensure that the RelationType has an indentity before using it to relate two entities
-            if (relationType.HasIdentity == false)
-                Save(relationType);
+            return Relate(parent.Id, child.Id, relationType);
+        }
 
-            var relation = new Relation(parent.Id, child.Id, relationType);
+        /// 
+        /// Relates two objects by their entity Ids.
+        /// 
+        /// Id of the parent
+        /// Id of the child
+        /// Alias of the type of relation to create
+        /// The created 
+        public IRelation Relate(int parentId, int childId, string relationTypeAlias)
+        {
+            var relationType = GetRelationTypeByAlias(relationTypeAlias);
+            if (relationType == null || string.IsNullOrEmpty(relationType.Alias))
+                throw new ArgumentNullException(string.Format("No RelationType with Alias '{0}' exists.", relationTypeAlias));
 
-            using (var uow = UowProvider.GetUnitOfWork())
-            {
-                var repository = RepositoryFactory.CreateRelationRepository(uow);
-                var saveEventArgs = new SaveEventArgs(relation);
-                if (uow.Events.DispatchCancelable(SavingRelation, this, saveEventArgs))
-                {
-                    uow.Commit();
-                    return relation;
-                }
-
-                repository.AddOrUpdate(relation);
-                uow.Commit();
-                saveEventArgs.CanCancel = false;
-                uow.Events.Dispatch(SavedRelation, this, saveEventArgs);
-                return relation;
-            }
+            return Relate(parentId, childId, relationType);
         }
 
         /// 
@@ -440,23 +468,7 @@ namespace Umbraco.Core.Services
             if (relationType == null || string.IsNullOrEmpty(relationType.Alias))
                 throw new ArgumentNullException(string.Format("No RelationType with Alias '{0}' exists.", relationTypeAlias));
 
-            var relation = new Relation(parent.Id, child.Id, relationType);
-
-            using (var uow = UowProvider.GetUnitOfWork())
-            {
-                var saveEventArgs = new SaveEventArgs(relation);
-                if (uow.Events.DispatchCancelable(SavingRelation, this, saveEventArgs))
-                {
-                    uow.Commit();
-                    return relation;
-                }
-                var repository = RepositoryFactory.CreateRelationRepository(uow);
-                repository.AddOrUpdate(relation);
-                uow.Commit();
-                saveEventArgs.CanCancel = false;
-                uow.Events.Dispatch(SavedRelation, this, saveEventArgs);
-                return relation;
-            }
+            return Relate(parent.Id, child.Id, relationType);
         }
 
         /// 

From 639ef53c88d0bdb2e46f175e264fb379ffd39c18 Mon Sep 17 00:00:00 2001
From: leekelleher 
Date: Thu, 5 Apr 2018 17:56:10 +0100
Subject: [PATCH 007/111] U4-9088 - Macro Container Property Type returned
 incorrect object-type

The `PropertyValueType` attribute marks this converter as returning an `IHtmlString`, but `ConvertDataToSource` returns a `string` type.
This patch corrects the return type to be a `HtmlString`.
---
 .../ValueConverters/MacroContainerValueConverter.cs         | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MacroContainerValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MacroContainerValueConverter.cs
index 436d131bcd..74ad2090ff 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MacroContainerValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MacroContainerValueConverter.cs
@@ -12,7 +12,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
     /// Ensures macro syntax is parsed for the macro container which will work when getting the field
     /// values in any way (i.e. dynamically, using Field(), or IPublishedContent)
     /// 
-    [PropertyValueType(typeof (IHtmlString))]
+    [PropertyValueType(typeof(IHtmlString))]
     [PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Request)]
     [DefaultPropertyValueConverter]
     public class MacroContainerValueConverter : PropertyValueConverterBase
@@ -64,7 +64,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
             // ensure string is parsed for macros and macros are executed correctly
             sourceString = RenderMacros(sourceString, preview);
 
-            return sourceString;
+            return new HtmlString(sourceString);
         }
     }
-}
\ No newline at end of file
+}

From 6abd778fd9befb90c60f145df928b9115bb36435 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Vanbrabandt?= 
Date: Sat, 7 Apr 2018 13:50:10 +0200
Subject: [PATCH 008/111] Fix wrong closing i tag and wrong title for edit
 button

---
 .../src/views/components/umb-node-preview.html                | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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 d04de47757..eee7b84360 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 @@
         
     
     
 
 

From 78121dd0f2e8d93daba1f68235f1d2e7df37e1dd Mon Sep 17 00:00:00 2001
From: AndyButland 
Date: Mon, 9 Apr 2018 08:52:54 +0200
Subject: [PATCH 009/111] Re-send of invitation from user profile. Allow delete
 of users that haven't logged in from user profile. Prevent disable/enable and
 change password options from user profile for invited users.

---
 .../src/common/resources/users.resource.js    | 33 ++++++++++++-
 .../src/views/users/user.controller.js        | 46 ++++++++++++++++++-
 .../src/views/users/views/user/details.html   | 34 ++++++++++++--
 src/Umbraco.Web.UI/umbraco/config/lang/en.xml |  7 +++
 .../umbraco/config/lang/en_us.xml             |  7 +++
 src/Umbraco.Web/Editors/UsersController.cs    | 32 +++++++++++++
 6 files changed, 154 insertions(+), 5 deletions(-)

diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/users.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/users.resource.js
index 72564398c0..0fd308ffd0 100644
--- a/src/Umbraco.Web.UI.Client/src/common/resources/users.resource.js
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/users.resource.js
@@ -280,7 +280,7 @@
           *    });
           * 
* - * @param {Array} id user id. + * @param {Int} userId user id. * @returns {Promise} resourcePromise object containing the user. * */ @@ -406,6 +406,36 @@ "Failed to save user"); } + /** + * @ngdoc method + * @name umbraco.resources.usersResource#deleteNonLoggedInUser + * @methodOf umbraco.resources.usersResource + * + * @description + * Deletes a user that hasn't already logged in (and hence we know has made no content updates that would create related records) + * + * ##usage + *
+          * usersResource.deleteNonLoggedInUser(1)
+          *    .then(function() {
+          *        alert("user was deleted");
+          *    });
+          * 
+ * + * @param {Int} userId user id. + * @returns {Promise} resourcePromise object. + * + */ + function deleteNonLoggedInUser(userId) { + + return umbRequestHelper.resourcePromise( + $http.post( + umbRequestHelper.getApiUrl( + "userApiBaseUrl", + "PostDeleteNonLoggedInUser", { id: userId })), + 'Failed to delete the user ' + userId); + } + var resource = { disableUsers: disableUsers, @@ -417,6 +447,7 @@ createUser: createUser, inviteUser: inviteUser, saveUser: saveUser, + deleteNonLoggedInUser: deleteNonLoggedInUser, clearAvatar: clearAvatar }; diff --git a/src/Umbraco.Web.UI.Client/src/views/users/user.controller.js b/src/Umbraco.Web.UI.Client/src/views/users/user.controller.js index 0f3519c7ba..a1b30e38b7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/user.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/users/user.controller.js @@ -31,6 +31,8 @@ vm.disableUser = disableUser; vm.enableUser = enableUser; vm.unlockUser = unlockUser; + vm.resendInvite = resendInvite; + vm.deleteNonLoggedInUser = deleteNonLoggedInUser; vm.changeAvatar = changeAvatar; vm.clearAvatar = clearAvatar; vm.save = save; @@ -49,7 +51,9 @@ "sections_users", "content_contentRoot", "media_mediaRoot", - "user_noStartNodes" + "user_noStartNodes", + "user_defaultInvitationMessage", + "user_deleteUserConfirmation" ]; localizationService.localizeMany(labelKeys).then(function (values) { @@ -61,6 +65,8 @@ vm.labels.contentRoot = values[5]; vm.labels.mediaRoot = values[6]; vm.labels.noStartNodes = values[7]; + vm.labels.defaultInvitationMessage = values[8]; + vm.labels.deleteUserConfirmation = values[9]; }); // get user @@ -350,6 +356,44 @@ }); } + function resendInvite() { + vm.resendInviteButtonState = "busy"; + + if (vm.resendInviteMessage) { + vm.user.message = vm.resendInviteMessage; + } + else { + vm.user.message = vm.labels.defaultInvitationMessage; + } + + usersResource.inviteUser(vm.user).then(function (data) { + vm.resendInviteButtonState = "success"; + vm.resendInviteMessage = ""; + formHelper.showNotifications(data); + }, function (error) { + vm.resendInviteButtonState = "error"; + formHelper.showNotifications(error.data); + }); + } + + function deleteNonLoggedInUser() { + vm.deleteNotLoggedInUserButtonState = "busy"; + + var confirmationMessage = vm.labels.deleteUserConfirmation; + if (!confirm(confirmationMessage)) { + vm.deleteNotLoggedInUserButtonState = "danger"; + return; + } + + usersResource.deleteNonLoggedInUser(vm.user.id).then(function (data) { + formHelper.showNotifications(data); + goToPage(vm.breadcrumbs[0]); + }, function (error) { + vm.deleteNotLoggedInUserButtonState = "error"; + formHelper.showNotifications(error.data); + }); + } + function clearAvatar() { // get user usersResource.clearAvatar(vm.user.id).then(function (data) { diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html index 67f204aa2f..8b9be7acdc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html @@ -239,7 +239,7 @@
-
- + + + +
+ + + +
+
Last login: @@ -358,4 +386,4 @@
-
\ 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 0137e5d0e0..bdc2b0cd6f 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -46,6 +46,7 @@ Set permissions Unlock Create Content Template + Resend Invitation Content @@ -1419,6 +1420,9 @@ To manage your website, simply open the Umbraco back office and start adding con An error occurred while unlocking the user Member was exported to file An error occurred while exporting the member + User %0% was deleted + Invite user + Invitation has been re-sent to %0% Uses CSS syntax ex: h1, .redHeader, .blueTex @@ -1996,6 +2000,9 @@ To manage your website, simply open the Umbraco back office and start adding con ]]> Invite + Resending invitation... + Delete User + Are you sure you wish to delete this user account? 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 1ff807b79b..e1db8003f6 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -46,6 +46,7 @@ Set permissions Unlock Create Content Template + Resend Invitation Content @@ -1416,6 +1417,9 @@ To manage your website, simply open the Umbraco back office and start adding con An error occurred while unlocking the user Member was exported to file An error occurred while exporting the member + User %0% was deleted + Invite user + Invitation has been re-sent to %0% Uses CSS syntax ex: h1, .redHeader, .blueTex @@ -1988,6 +1992,9 @@ To manage your website, simply open the Umbraco back office and start adding con ]]> Invite + Resending invitation... + Delete User + Are you sure you wish to delete this user account? Validation diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index f1670df346..f089c44afd 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -412,6 +412,8 @@ namespace Umbraco.Web.Editors await SendUserInviteEmailAsync(display, Security.CurrentUser.Name, Security.CurrentUser.Email, user, userSave.Message); + display.AddSuccessNotification(Services.TextService.Localize("speechBubbles/resendInviteHeader"), Services.TextService.Localize("speechBubbles/resendInviteSuccess", new[] { user.Name })); + return display; } @@ -699,6 +701,36 @@ namespace Umbraco.Web.Editors Services.TextService.Localize("speechBubbles/setUserGroupOnUsersSuccess")); } + /// + /// Deletes the non-logged in user provided id + /// + /// User Id + /// + /// Limited to users that haven't logged in to avoid issues with related records constrained + /// with a foreign key on the user Id + /// + public async Task PostDeleteNonLoggedInUser(int id) + { + var user = Services.UserService.GetUserById(id); + if (user == null) + { + throw new HttpResponseException(HttpStatusCode.NotFound); + } + + // Check user hasn't logged in. If they have they may have made content changes which will mean + // the Id is associated with audit trails, versions etc. and can't be removed. + if (user.LastLoginDate != default(DateTime)) + { + throw new HttpResponseException(HttpStatusCode.BadRequest); + } + + var userName = user.Name; + Services.UserService.Delete(user, true); + + return Request.CreateNotificationSuccessResponse( + Services.TextService.Localize("speechBubbles/deleteUserSuccess", new[] { userName })); + } + public class PagedUserResult : PagedResult { public PagedUserResult(long totalItems, long pageNumber, long pageSize) : base(totalItems, pageNumber, pageSize) From cabcb08b98781ab1cdac28ce9d1580423ef18c04 Mon Sep 17 00:00:00 2001 From: Damiaan Date: Mon, 9 Apr 2018 09:16:58 +0200 Subject: [PATCH 010/111] Typo in the docs reference Makes it hard to navigate the documentation :-) --- src/Umbraco.Core/Services/ConsentService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Services/ConsentService.cs b/src/Umbraco.Core/Services/ConsentService.cs index 674d042e1f..7f9b6b36ca 100644 --- a/src/Umbraco.Core/Services/ConsentService.cs +++ b/src/Umbraco.Core/Services/ConsentService.cs @@ -10,7 +10,7 @@ using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Services { /// - /// Implements . + /// Implements . /// internal class ConsentService : ScopeRepositoryService, IConsentService { From a5aa1b4db71179dd0a71d8279bb6260a37df76cd Mon Sep 17 00:00:00 2001 From: Robert Dyson Date: Fri, 13 Apr 2018 11:18:17 +0100 Subject: [PATCH 011/111] Allow capital letters for email address entry in RegesterModel --- src/Umbraco.Web/Models/RegisterModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Models/RegisterModel.cs b/src/Umbraco.Web/Models/RegisterModel.cs index b51f09b631..2764d316b9 100644 --- a/src/Umbraco.Web/Models/RegisterModel.cs +++ b/src/Umbraco.Web/Models/RegisterModel.cs @@ -47,7 +47,7 @@ namespace Umbraco.Web.Models } [Required] - [RegularExpression(@"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", + [RegularExpression(@"[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?", ErrorMessage = "Please enter a valid e-mail address")] public string Email { get; set; } From e3faa054352ed8393637890cd6b38bd672db9ccf Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Sun, 15 Apr 2018 19:03:38 +0200 Subject: [PATCH 012/111] Lookup member type to map this name of this to the MemberListDisplay model --- src/Umbraco.Web/Editors/MemberController.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web/Editors/MemberController.cs b/src/Umbraco.Web/Editors/MemberController.cs index 8ff7988a9a..7bc30d7b74 100644 --- a/src/Umbraco.Web/Editors/MemberController.cs +++ b/src/Umbraco.Web/Editors/MemberController.cs @@ -140,13 +140,16 @@ namespace Umbraco.Web.Editors /// public MemberListDisplay GetListNodeDisplay(string listName) { + var foundType = Services.MemberTypeService.Get(listName); + var name = foundType != null ? foundType.Name : listName; + var display = new MemberListDisplay { ContentTypeAlias = listName, - ContentTypeName = listName, + ContentTypeName = name, Id = listName, IsContainer = true, - Name = listName == Constants.Conventions.MemberTypes.AllMembersListId ? "All Members" : listName, + Name = listName == Constants.Conventions.MemberTypes.AllMembersListId ? "All Members" : name, Path = "-1," + listName, ParentId = -1 }; From 759e1f2e5a2e24aeaf65c7bf3395f3141096dcfc Mon Sep 17 00:00:00 2001 From: Dave Woestenborghs Date: Wed, 18 Apr 2018 08:27:03 +0200 Subject: [PATCH 013/111] U4-11233 make sure when a tour step is marked as intro get's displayed centered, even if element is set --- .../directives/components/application/umbtour.directive.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour.directive.js index 55641b6ec7..7e981c065d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbtour.directive.js @@ -304,6 +304,12 @@ In the following example you see how to run some custom logic before a step goes scope.elementNotFound = false; $timeout(function () { + // clear element when step as marked as intro, so it always displays in the center + if (scope.model.currentStep && scope.model.currentStep.type === "intro") { + scope.model.currentStep.element = null; + scope.model.currentStep.eventElement = null; + scope.model.currentStep.event = null; + } // if an element isn't set - show the popover in the center if(scope.model.currentStep && !scope.model.currentStep.element) { From 9ffca1bcab1674d7b28c1ee0a09bda6749e04583 Mon Sep 17 00:00:00 2001 From: Niels Hartvig Date: Mon, 30 Apr 2018 09:13:34 +0200 Subject: [PATCH 014/111] Implements doc type collections --- .../common/resources/contenttype.resource.js | 12 +++- .../views/documenttypes/create.controller.js | 38 ++++++++++++ .../src/views/documenttypes/create.html | 40 ++++++++++++- .../Editors/ContentTypeController.cs | 59 ++++++++++++++++++- .../DocumentTypeCollectionDisplay.cs | 14 +++++ src/Umbraco.Web/Umbraco.Web.csproj | 1 + 6 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 src/Umbraco.Web/Models/ContentEditing/DocumentTypeCollectionDisplay.cs diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js index 8bfcdfcc5a..43c13dded4 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js @@ -260,14 +260,22 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { 'Failed to copy content'); }, - createContainer: function(parentId, name) { + createContainer: function (parentId, name) { return umbRequestHelper.resourcePromise( - $http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "PostCreateContainer", { parentId: parentId, name: name })), + $http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "PostCreateContainer", { parentId: parentId, name: name })), 'Failed to create a folder under parent id ' + parentId); }, + createCollection: function (parentId, collectionName, itemName) { + + return umbRequestHelper.resourcePromise( + $http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "PostCreateCollection", { parentId: parentId, collectionName: collectionName, itemName: itemName})), + 'Failed to create collection under ' + parentId); + + }, + renameContainer: function(id, name) { return umbRequestHelper.resourcePromise( diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.controller.js index aade96c3cc..165c6e6f2a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.controller.js @@ -12,6 +12,7 @@ function DocumentTypesCreateController($scope, $location, navigationService, con allowCreateFolder: $scope.dialogOptions.currentNode.parentId === null || $scope.dialogOptions.currentNode.nodeType === "container", folderName: "", creatingFolder: false, + creatingDoctypeCollection: false }; var disableTemplates = Umbraco.Sys.ServerVariables.features.disabledFeatures.disableTemplates; @@ -24,6 +25,10 @@ function DocumentTypesCreateController($scope, $location, navigationService, con $scope.model.creatingFolder = true; }; + $scope.showCreateDocTypeCollection = function () { + $scope.model.creatingDoctypeCollection = true; + }; + $scope.createContainer = function () { if (formHelper.submitForm({ scope: $scope, formCtrl: this.createFolderForm, statusMessage: localizeCreateFolder })) { @@ -61,6 +66,39 @@ function DocumentTypesCreateController($scope, $location, navigationService, con } }; + $scope.createCollection = function () { + + if (formHelper.submitForm({ scope: $scope, formCtrl: this.createDoctypeCollectionForm, statusMessage: "Creating Doctype Collection..." })) { + + contentTypeResource.createCollection(node.id, $scope.model.collectionName, $scope.model.collectionItemName).then(function (collectionData) { + + navigationService.hideMenu(); + $location.search('create', null); + $location.search('notemplate', null); + + formHelper.resetForm({ + scope: $scope + }); + + var section = appState.getSectionState("currentSection"); + + // redirect to the item id + $location.path("/settings/documenttypes/edit/" + collectionData.ItemId); + + }, function (err) { + + $scope.error = err; + + //show any notifications + if (angular.isArray(err.data.notifications)) { + for (var i = 0; i < err.data.notifications.length; i++) { + notificationsService.showNotification(err.data.notifications[i]); + } + } + }); + } + }; + // Disabling logic for creating document type with template if disableTemplates is set to true if (!disableTemplates) { $scope.createDocType = function () { diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.html index e5043be785..549ad0452b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/create.html @@ -1,6 +1,6 @@