From 3d52f2676ed1cab1602a6f8129187162d0e3f920 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 16 Oct 2018 10:59:04 +0200 Subject: [PATCH 01/52] Add possibility to extend the umb-box-header + add rollback button --- .../content/umbcontentnodeinfo.directive.js | 4 ++++ .../src/less/components/umb-box.less | 3 +++ .../content/umb-content-node-info.html | 12 +++++++++++- .../html/umb-box/umb-box-header.html | 19 +++++++++++-------- 4 files changed, 29 insertions(+), 9 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 b2e64983d6..d274cb495c 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 @@ -101,6 +101,10 @@ scope.node.template = templateAlias; }; + scope.openRollback = function() { + console.log("rollback"); + }; + function loadAuditTrail() { scope.loadingAuditTrail = true; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-box.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-box.less index f2cacc26b3..fb83504a1f 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-box.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-box.less @@ -8,6 +8,9 @@ .umb-box-header { padding: 10px 20px; border-bottom: 1px solid @gray-9; + display: flex; + align-items: center; + justify-content: space-between; } .umb-box-header-title { 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 03d4318ba2..9849ba0c08 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 @@ -41,7 +41,17 @@ - + + + + + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/html/umb-box/umb-box-header.html b/src/Umbraco.Web.UI.Client/src/views/components/html/umb-box/umb-box-header.html index 8c59061788..e9f771f09c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/html/umb-box/umb-box-header.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/html/umb-box/umb-box-header.html @@ -1,10 +1,13 @@ -
-
- - {{title}} -
-
- - {{description}} +
+
+
+ + {{title}} +
+
+ + {{description}} +
+
\ No newline at end of file From eceec9ea3e431fc02e6a33e8b3470361b1c2dd33 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 16 Oct 2018 11:43:14 +0200 Subject: [PATCH 02/52] Set rollback button to be xs + fix padding on xs buttons --- .../src/less/components/buttons/umb-button.less | 2 +- .../src/views/components/content/umb-content-node-info.html | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button.less b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button.less index 4b670ab781..d3f2fee5d5 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button.less @@ -104,7 +104,7 @@ } .umb-button--xs { - padding: 5px 16px; + padding: 5px 13px; font-size: 14px; } 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 9849ba0c08..77a7161762 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 @@ -48,7 +48,8 @@ type="button" button-style="outline" action="openRollback()" - label-key="actions_rollback"> + label-key="actions_rollback" + size="xs"> From 1c1057412ecad3fd9472fc16b3cadd0cf4a1b07f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 16 Oct 2018 12:40:40 +0200 Subject: [PATCH 03/52] move current rollback version to infinite editor --- .../content/umbcontentnodeinfo.directive.js | 10 ++ .../src/common/services/editor.service.js | 20 +++ .../rollback/rollback.controller.js | 129 ++++++++++++++++++ .../infiniteeditors/rollback/rollback.html | 92 +++++++++++++ 4 files changed, 251 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html 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 d274cb495c..416774d6b4 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 @@ -103,6 +103,16 @@ scope.openRollback = function() { console.log("rollback"); + var rollback = { + node: scope.node, + submit: function(model) { + editorService.close(); + }, + close: function() { + editorService.close(); + } + }; + editorService.rollback(rollback); }; function loadAuditTrail() { diff --git a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js index eab167c2ec..7d1ef3e9b9 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js @@ -180,6 +180,25 @@ open(editor); } + /** + * @ngdoc method + * @name umbraco.services.editorService#rollback + * @methodOf umbraco.services.editorService + * + * @description + * Opens a rollback editor in infinite editing. + * @param {String} editor.node The node to rollback + * @param {Callback} editor.submit Saves, submits, and closes the editor + * @param {Callback} editor.close Closes the editor + * @returns {Object} editor object + */ + + function rollback(editor) { + editor.view = "views/common/infiniteeditors/rollback/rollback.html"; + editor.size = "small"; + open(editor); + } + /** * @ngdoc method * @name umbraco.services.editorService#linkPicker @@ -481,6 +500,7 @@ copy: copy, move: move, embed: embed, + rollback: rollback, linkPicker: linkPicker, mediaPicker: mediaPicker, iconPicker: iconPicker, diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js new file mode 100644 index 0000000000..8ed6f68df6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js @@ -0,0 +1,129 @@ +(function () { + "use strict"; + + function RollbackController($scope, localizationService, assetsService) { + + var vm = this; + + vm.rollback = rollback; + vm.loadVersion = loadVersion; + vm.submit = submit; + vm.close = close; + + ////////// + + function onInit() { + + vm.loading = true; + vm.variantVersions = []; + vm.diff = null; + + // set default title + if(!$scope.model.title) { + localizationService.localize("actions_rollback").then(function(value){ + $scope.model.title = value; + }); + } + + // Load in diff library + assetsService.loadJs('lib/jsdiff/diff.min.js', $scope).then(function () { + + vm.currentVersion = { + "id": 1, + "createDate": "22/08/2018 13.32", + "name": "Forside", + "properties": [ + { + "alias": "headline", + "label": "Headline", + "value": "Velkommen" + }, + { + "alias": "text", + "label": "Text", + "value": "This is my danish Content" + } + ] + }; + + vm.previousVersions = [ + { + "id": 2, + "name": "Forside", + "createDate": "21/08/2018 19.25" + } + ]; + + vm.loading = false; + + }); + + } + + function rollback() { + console.log("rollback"); + } + + /** + * This will load in a new version + */ + function loadVersion(id) { + + // fake load version + + vm.diff = {}; + vm.diff.properties = []; + + var oldVersion = { + "id": 2, + "name": "Foride", + "properties": [ + { + "alias": "headline", + "label": "Headline", + "value": "" + }, + { + "alias": "text", + "label": "Text", + "value": "This is my danish Content Test" + } + ] + }; + + // find diff in name + vm.diff.name = JsDiff.diffWords(vm.currentVersion.name, oldVersion.name); + + // find diff in properties + angular.forEach(vm.currentVersion.properties, + function(newProperty, index){ + var oldProperty = oldVersion.properties[index]; + var diffProperty = { + "alias": newProperty.alias, + "label": newProperty.label, + "diff": JsDiff.diffWords(newProperty.value, oldProperty.value) + }; + vm.diff.properties.push(diffProperty); + }); + + } + + function submit(model) { + if($scope.model.submit) { + $scope.model.submit(model); + } + } + + function close() { + if($scope.model.close) { + $scope.model.close(); + } + } + + onInit(); + + } + + angular.module("umbraco").controller("Umbraco.Editors.RollbackController", RollbackController); + +})(); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html new file mode 100644 index 0000000000..a09f91632a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html @@ -0,0 +1,92 @@ +
+ + + + + + + + + + + + + + +
+ +
+

{{vm.currentVersion.name}} (Created: {{vm.currentVersion.createDate}})

+ +
+ +
+ +
+ +
Changes
+ + + + + + + + + + + + + +
Name + + {{part.value}} + {{part.value}} + {{part.value}} + +
{{property.label}} + + {{part.value}} + {{part.value}} + {{part.value}} + +
+ +
+ +
+
+
+ + + + + + + + + + +
+ +
\ No newline at end of file From 203ea8019b6d40cb2beeb38553ab8e28414b01c9 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 16 Oct 2018 14:09:57 +0200 Subject: [PATCH 04/52] add language selector --- .../infiniteeditors/rollback/rollback.controller.js | 11 +++++++++++ .../common/infiniteeditors/rollback/rollback.html | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js index 8ed6f68df6..dc42568d54 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js @@ -18,6 +18,17 @@ vm.variantVersions = []; vm.diff = null; + // preselect the active language + if($scope.model.node.variants.length > 1) { + var active = _.find($scope.model.node.variants, function (v) { + return v.active; + }); + + if(active) { + vm.selectedVariant = active; + } + } + // set default title if(!$scope.model.title) { localizationService.localize("actions_rollback").then(function(value){ diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html index a09f91632a..ef474551df 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html @@ -18,6 +18,17 @@ + +
+
+ +
From 16282e10074a9761a288791d105b092dcae35c30 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 16 Oct 2018 14:37:00 +0200 Subject: [PATCH 05/52] remove old client side files for rollback --- .../content/content.rollback.controller.js | 117 ------------------ .../src/views/content/rollback.html | 80 ------------ 2 files changed, 197 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/src/views/content/content.rollback.controller.js delete mode 100644 src/Umbraco.Web.UI.Client/src/views/content/rollback.html diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.rollback.controller.js deleted file mode 100644 index 9da43b1430..0000000000 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.rollback.controller.js +++ /dev/null @@ -1,117 +0,0 @@ -(function () { - "use strict"; - - function ContentRollbackController($scope, assetsService) { - - var vm = this; - - vm.rollback = rollback; - vm.loadVersion = loadVersion; - vm.closeDialog = closeDialog; - - function onInit() { - - vm.loading = true; - vm.variantVersions = []; - vm.diff = null; - - // Load in diff library - assetsService.loadJs('lib/jsdiff/diff.min.js', $scope).then(function () { - - var currentLanguage = $scope.currentNode.metaData.culture; - - vm.currentVersion = { - "id": 1, - "createDate": "22/08/2018 13.32", - "name": "Forside", - "properties": [ - { - "alias": "headline", - "label": "Headline", - "value": "Velkommen" - }, - { - "alias": "text", - "label": "Text", - "value": "This is my danish Content" - } - ] - }; - - vm.previousVersions = [ - { - "id": 2, - "name": "Forside", - "createDate": "21/08/2018 19.25" - } - ]; - - vm.loading = false; - - }); - - } - - function rollback() { - console.log("rollback"); - } - - /** - * This will load in a new version - */ - function loadVersion(id) { - - // fake load version - var currentLanguage = $scope.currentNode.metaData.culture; - - vm.diff = {}; - vm.diff.properties = []; - - var oldVersion = { - "id": 2, - "name": "Foride", - "properties": [ - { - "alias": "headline", - "label": "Headline", - "value": "" - }, - { - "alias": "text", - "label": "Text", - "value": "This is my danish Content Test" - } - ] - }; - - // find diff in name - vm.diff.name = JsDiff.diffWords(vm.currentVersion.name, oldVersion.name); - - // find diff in properties - angular.forEach(vm.currentVersion.properties, - function(newProperty, index){ - var oldProperty = oldVersion.properties[index]; - var diffProperty = { - "alias": newProperty.alias, - "label": newProperty.label, - "diff": JsDiff.diffWords(newProperty.value, oldProperty.value) - }; - vm.diff.properties.push(diffProperty); - }); - - } - - /** - * This will close the dialog - */ - function closeDialog() { - $scope.nav.hideDialog(); - } - - onInit(); - - } - - angular.module("umbraco").controller("Umbraco.Editors.Content.RollbackController", ContentRollbackController); - -})(); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/content/rollback.html b/src/Umbraco.Web.UI.Client/src/views/content/rollback.html deleted file mode 100644 index 389b8f30db..0000000000 --- a/src/Umbraco.Web.UI.Client/src/views/content/rollback.html +++ /dev/null @@ -1,80 +0,0 @@ -
- -
- - - -
- -
-
Rollback {{ currentNode.name }}
- -
-

{{vm.currentVersion.name}} (Created: {{vm.currentVersion.createDate}})

- -
- -
- -
- -
Changes
- - - - - - - - - - - - - -
Name - - {{part.value}} - {{part.value}} - {{part.value}} - -
{{property.label}} - - {{part.value}} - {{part.value}} - {{part.value}} - -
- -
- -
-
- - - -
\ No newline at end of file From fd6f9fc83b2a25cdd6d76d45ca7fd52724f32687 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 16 Oct 2018 15:11:47 +0200 Subject: [PATCH 06/52] remove rollback context menu item --- src/Umbraco.Web/Trees/ContentTreeController.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index 3a990a7741..436c65d95d 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -238,7 +238,6 @@ namespace Umbraco.Web.Trees AddActionNode(item, menu, true); - AddActionNode(item, menu); AddActionNode(item, menu, convert: true); AddActionNode(item, menu); AddActionNode(item, menu, convert: true); From 5c796b15ade151e018e93e20b7cc2c1914099e0e Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 17 Oct 2018 11:01:33 +0200 Subject: [PATCH 07/52] Remove console.log --- .../components/content/umbcontentnodeinfo.directive.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 416774d6b4..327d99a8c6 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 @@ -102,7 +102,7 @@ }; scope.openRollback = function() { - console.log("rollback"); + var rollback = { node: scope.node, submit: function(model) { From c05495f3587d29f41c33728284cf58d8708560d5 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 17 Oct 2018 12:15:57 +0100 Subject: [PATCH 08/52] WIP: Adds a new API endpoint in the editor/webapi for ContenController to list rollback versions available for a culture --- src/Umbraco.Web/Editors/ContentController.cs | 56 +++++++++++++++++++ .../Models/ContentEditing/RollbackVersion.cs | 13 +++++ src/Umbraco.Web/Umbraco.Web.csproj | 1 + 3 files changed, 70 insertions(+) create mode 100644 src/Umbraco.Web/Models/ContentEditing/RollbackVersion.cs diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 1fcee6d727..d35a801766 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1702,5 +1702,61 @@ namespace Umbraco.Web.Editors Services.NotificationService.SetNotifications(Security.CurrentUser, content, notifyOptions); } + [HttpGet] + public IEnumerable GetRollbackVersions(int contentId, string cultureName) + { + var rollbackVersions = new List(); + + //Return a list of all versions of a specific content node + var versions = Services.ContentService.GetVersions(contentId); + + //Not all nodes are variants & thus culture can be null + //Only filter the collection + if(cultureName != null) + { + versions = versions.Where(x => x.PublishDate == x.GetPublishDate(cultureName)); + } + + foreach(var version in versions) + { + var rollbackVersion = new RollbackVersion(); + + //Version ID + rollbackVersion.VersionId = version.VersionId; + + //Date of version + var cultureDate = version.GetPublishDate(cultureName); + if (cultureDate.HasValue) + { + rollbackVersion.VersionDate = cultureDate.Value; + } + else if (version.PublishDate.HasValue) + { + rollbackVersion.VersionDate = version.PublishDate.Value; + } + + //Name of publisher + //TODO: Reviewer would this extra info be expensive? + var publisherId = version.PublisherId; + + if (publisherId.HasValue) + { + var publisher = Services.UserService.GetUserById(version.PublisherId.Value); + rollbackVersion.VersionAuthorName = publisher.Name; + } + + rollbackVersions.Add(rollbackVersion); + } + + return rollbackVersions; + } + + //[EnsureUserPermissionForContent("id", 'D')] + [HttpPost] + public void PostRollback() + { + + } + } } diff --git a/src/Umbraco.Web/Models/ContentEditing/RollbackVersion.cs b/src/Umbraco.Web/Models/ContentEditing/RollbackVersion.cs new file mode 100644 index 0000000000..d496a89d35 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/RollbackVersion.cs @@ -0,0 +1,13 @@ +using System; + +namespace Umbraco.Web.Models.ContentEditing +{ + public class RollbackVersion + { + public int VersionId { get; set; } + + public DateTime VersionDate { get; set; } + + public string VersionAuthorName { get; set; } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index faf08849ce..5235728814 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -147,6 +147,7 @@ + From d9864eb6d6beda445b34c50a9927bab0a5560674 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 17 Oct 2018 13:19:09 +0100 Subject: [PATCH 09/52] * Make the culturename nullable for invariant content * fallback to update date and writer id if its not published --- src/Umbraco.Web/Editors/ContentController.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index d35a801766..0fe017925b 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1703,7 +1703,7 @@ namespace Umbraco.Web.Editors } [HttpGet] - public IEnumerable GetRollbackVersions(int contentId, string cultureName) + public IEnumerable GetRollbackVersions(int contentId, string cultureName = null) { var rollbackVersions = new List(); @@ -1730,20 +1730,17 @@ namespace Umbraco.Web.Editors { rollbackVersion.VersionDate = cultureDate.Value; } - else if (version.PublishDate.HasValue) + else { - rollbackVersion.VersionDate = version.PublishDate.Value; + rollbackVersion.VersionDate = version.UpdateDate; } //Name of publisher //TODO: Reviewer would this extra info be expensive? var publisherId = version.PublisherId; - - if (publisherId.HasValue) - { - var publisher = Services.UserService.GetUserById(version.PublisherId.Value); - rollbackVersion.VersionAuthorName = publisher.Name; - } + var userId = version.PublisherId.HasValue ? version.PublisherId.Value : version.WriterId; + var publisher = Services.UserService.GetUserById(userId); + rollbackVersion.VersionAuthorName = publisher.Name; rollbackVersions.Add(rollbackVersion); } From 27ce1f34bb43020526b5a07a75967ebd509610ee Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 17 Oct 2018 13:24:23 +0100 Subject: [PATCH 10/52] Make the JSON model over the API control be the correct casing & make Mads happy :) --- src/Umbraco.Web/Models/ContentEditing/RollbackVersion.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Umbraco.Web/Models/ContentEditing/RollbackVersion.cs b/src/Umbraco.Web/Models/ContentEditing/RollbackVersion.cs index d496a89d35..88df12883d 100644 --- a/src/Umbraco.Web/Models/ContentEditing/RollbackVersion.cs +++ b/src/Umbraco.Web/Models/ContentEditing/RollbackVersion.cs @@ -1,13 +1,18 @@ using System; +using System.Runtime.Serialization; namespace Umbraco.Web.Models.ContentEditing { + [DataContract(Name = "rollbackVersion", Namespace = "")] public class RollbackVersion { + [DataMember(Name = "versionId")] public int VersionId { get; set; } + [DataMember(Name = "versionDate")] public DateTime VersionDate { get; set; } + [DataMember(Name = "versionAuthorName")] public string VersionAuthorName { get; set; } } } From 2be227358961e53584441d8d3f0303ca8f44938b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 17 Oct 2018 14:33:42 +0200 Subject: [PATCH 11/52] wire up versions end point --- .../src/common/resources/content.resource.js | 32 +++++++++++++++++++ .../rollback/rollback.controller.js | 17 +++++----- .../infiniteeditors/rollback/rollback.html | 2 +- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js index 721cd4da57..8de368be1a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js @@ -808,6 +808,38 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { ), "Failed to create blueprint from content with id " + contentId ); + }, + + /** + * @ngdoc method + * @name umbraco.resources.contentResource#getRollbackVersions + * @methodOf umbraco.resources.contentResource + * + * @description + * Returns an array of previous version id's, given a node id and a culture + * + * ##usage + *
+          * contentResource.getRollbackVersions(id, culture)
+          *    .then(function(versions) {
+          *        alert('its here!');
+          *    });
+          * 
+ * + * @param {Int} id Id of node + * @param {Int} culture if provided, the results will be for this specific culture/variant + * @returns {Promise} resourcePromise object containing the url. + * + */ + getRollbackVersions: function (contentId, culture) { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl("contentApiBaseUrl", "GetRollbackVersions", { + contentId: contentId, cultureName: culture + }) + ), + "Failed to get rollback versions for content item with id " + contentId + ); } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js index dc42568d54..ec5b3f2242 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function RollbackController($scope, localizationService, assetsService) { + function RollbackController($scope, contentResource, localizationService, assetsService) { var vm = this; @@ -57,13 +57,14 @@ ] }; - vm.previousVersions = [ - { - "id": 2, - "name": "Forside", - "createDate": "21/08/2018 19.25" - } - ]; + const nodeId = $scope.model.node.id; + const culture = vm.selectedVariant ? vm.selectedVariant.language.culture : null; + + contentResource.getRollbackVersions(nodeId, culture) + .then(function(data){ + console.log(data); + vm.previousVersions = data; + }); vm.loading = false; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html index ef474551df..a4f571f832 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html @@ -39,7 +39,7 @@ From 214d6a9834bed546194101f1490691f082ffe7ba Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 17 Oct 2018 15:17:43 +0200 Subject: [PATCH 12/52] show correct title and date for current version + update versions when language is changed --- .../rollback/rollback.controller.js | 66 ++++++++++--------- .../infiniteeditors/rollback/rollback.html | 6 +- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js index ec5b3f2242..cbbc4dd182 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js @@ -7,6 +7,8 @@ vm.rollback = rollback; vm.loadVersion = loadVersion; + vm.changeLanguage = changeLanguage; + vm.changeVersion = changeVersion; vm.submit = submit; vm.close = close; @@ -17,15 +19,23 @@ vm.loading = true; vm.variantVersions = []; vm.diff = null; + vm.currentVersion = null; - // preselect the active language + // find the current version for invariant nodes + if($scope.model.node.variants.length === 1) { + vm.currentVersion = $scope.model.node.variants[0]; + } + + // find the current version for nodes with variants if($scope.model.node.variants.length > 1) { var active = _.find($scope.model.node.variants, function (v) { return v.active; }); + // preselect the language in the dropdown if(active) { - vm.selectedVariant = active; + vm.selectedLanguage = active; + vm.currentVersion = active; } } @@ -39,39 +49,35 @@ // Load in diff library assetsService.loadJs('lib/jsdiff/diff.min.js', $scope).then(function () { - vm.currentVersion = { - "id": 1, - "createDate": "22/08/2018 13.32", - "name": "Forside", - "properties": [ - { - "alias": "headline", - "label": "Headline", - "value": "Velkommen" - }, - { - "alias": "text", - "label": "Text", - "value": "This is my danish Content" - } - ] - }; - - const nodeId = $scope.model.node.id; - const culture = vm.selectedVariant ? vm.selectedVariant.language.culture : null; - - contentResource.getRollbackVersions(nodeId, culture) - .then(function(data){ - console.log(data); - vm.previousVersions = data; - }); - - vm.loading = false; + getVersions().then(function(){ + vm.loading = false; + }); }); } + function changeLanguage(language) { + vm.currentVersion = language; + getVersions(); + } + + function changeVersion(version) { + console.log("version", version); + } + + function getVersions() { + + const nodeId = $scope.model.node.id; + const culture = $scope.model.node.variants.length > 1 ? vm.currentVersion.language.culture : null; + + return contentResource.getRollbackVersions(nodeId, culture) + .then(function(data){ + console.log("new", data); + vm.previousVersions = data; + }); + } + function rollback() { console.log("rollback"); } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html index a4f571f832..6a17cac09b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html @@ -23,9 +23,9 @@
@@ -40,7 +40,7 @@ class="input-block-level" ng-model="vm.selectedVersion" ng-options="version.versionDate for version in vm.previousVersions track by version.versionId" - ng-change="vm.loadVersion(vm.selectedVersion.id)"> + ng-change="vm.changeVersion(vm.selectedVersion.id)">
From 2baafd9c9195a05336d47f4b3b91e4a87157a8ef Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 17 Oct 2018 14:39:11 +0100 Subject: [PATCH 13/52] * Renamed API variables to 'culture' to make Stephan happy - updated the AngularJS HTTP Resource call too * Stubbed out some other WIP code - for getting a specific version & attempting to perform a rollback --- .../src/common/resources/content.resource.js | 2 +- src/Umbraco.Web/Editors/ContentController.cs | 48 +++++++++++++++---- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js index 8de368be1a..6c0cb5e6b2 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js @@ -835,7 +835,7 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { return umbRequestHelper.resourcePromise( $http.get( umbRequestHelper.getApiUrl("contentApiBaseUrl", "GetRollbackVersions", { - contentId: contentId, cultureName: culture + contentId: contentId, culture: culture }) ), "Failed to get rollback versions for content item with id " + contentId diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 0fe017925b..85b42e59c3 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1703,7 +1703,7 @@ namespace Umbraco.Web.Editors } [HttpGet] - public IEnumerable GetRollbackVersions(int contentId, string cultureName = null) + public IEnumerable GetRollbackVersions(int contentId, string culture = null) { var rollbackVersions = new List(); @@ -1712,10 +1712,10 @@ namespace Umbraco.Web.Editors //Not all nodes are variants & thus culture can be null //Only filter the collection - if(cultureName != null) - { - versions = versions.Where(x => x.PublishDate == x.GetPublishDate(cultureName)); - } + //if(cultureName != null) + //{ + // versions = versions.Where(x => x.PublishDate == x.GetPublishDate(culture)); + //} foreach(var version in versions) { @@ -1725,7 +1725,7 @@ namespace Umbraco.Web.Editors rollbackVersion.VersionId = version.VersionId; //Date of version - var cultureDate = version.GetPublishDate(cultureName); + var cultureDate = version.GetPublishDate(culture); if (cultureDate.HasValue) { rollbackVersion.VersionDate = cultureDate.Value; @@ -1748,12 +1748,40 @@ namespace Umbraco.Web.Editors return rollbackVersions; } - //[EnsureUserPermissionForContent("id", 'D')] - [HttpPost] - public void PostRollback() + [HttpGet] + public ContentItemDisplay GetRollbackVersion(int versionId) { - + var version = Services.ContentService.GetVersion(versionId); + var content = MapToDisplay(version); + return content; } + [HttpPost] + public HttpResponseMessage PostRollbackContent(int contentId, int versionId, string culture = "*") + { + //TODO: Do we log something - so there is a trail in the logs + //Of who performed the rollback of what document, time + + //Get the current copy of the node + var content = Services.ContentService.GetById(contentId); + + //Get the version + var version = Services.ContentService.GetVersion(versionId); + + //Copy the changes from the version + content.CopyFrom(version); + + //Save & Publish the update + var publishResult = Services.ContentService.SaveAndPublish(content, culture, Security.GetUserId().ResultOr(0)); + if (publishResult.Success == false) + { + var notificationModel = new SimpleNotificationModel(); + AddMessageForPublishStatus(publishResult, notificationModel); + return Request.CreateValidationErrorResponse(notificationModel); + } + + //return ok + return Request.CreateResponse(HttpStatusCode.OK); + } } } From eb8b2698460eaf9766a2aa438093a90c5e725aae Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 17 Oct 2018 16:02:47 +0200 Subject: [PATCH 14/52] wire up getRollbackVersion endpoint --- .../src/common/resources/content.resource.js | 33 +++++++++++++++++++ .../rollback/rollback.controller.js | 9 +++-- .../infiniteeditors/rollback/rollback.html | 2 +- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js index 6c0cb5e6b2..34a61cca91 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js @@ -840,9 +840,42 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { ), "Failed to get rollback versions for content item with id " + contentId ); + }, + + + /** + * @ngdoc method + * @name umbraco.resources.contentResource#getRollbackVersion + * @methodOf umbraco.resources.contentResource + * + * @description + * Returns a previous version of a content item + * + * ##usage + *
+          * contentResource.getRollbackVersion(versionId)
+          *    .then(function(version) {
+          *        alert('its here!');
+          *    });
+          * 
+ * + * @param {Int} versionId The version Id + * @returns {Promise} resourcePromise object containing the url. + * + */ + getRollbackVersion: function (versionId) { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl("contentApiBaseUrl", "GetRollbackVersion", { + versionId: versionId + }) + ), + "Failed to get version for content item with id " + versionId + ); } + }; } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js index cbbc4dd182..24fab8f30a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js @@ -6,7 +6,6 @@ var vm = this; vm.rollback = rollback; - vm.loadVersion = loadVersion; vm.changeLanguage = changeLanguage; vm.changeVersion = changeVersion; vm.submit = submit; @@ -64,6 +63,12 @@ function changeVersion(version) { console.log("version", version); + contentResource.getRollbackVersion(version.versionId) + .then(function(data){ + console.log(data); + //createDiff(vm.currentVersion, data); + }); + } function getVersions() { @@ -85,7 +90,7 @@ /** * This will load in a new version */ - function loadVersion(id) { + function createDiff(currentVersion, previousVersion) { // fake load version diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html index 6a17cac09b..70dd189328 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html @@ -40,7 +40,7 @@ class="input-block-level" ng-model="vm.selectedVersion" ng-options="version.versionDate for version in vm.previousVersions track by version.versionId" - ng-change="vm.changeVersion(vm.selectedVersion.id)"> + ng-change="vm.changeVersion(vm.selectedVersion)">
From fff7891e533d76d2d1835013e96c46f869cbadd4 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 17 Oct 2018 15:09:29 +0100 Subject: [PATCH 15/52] Filter rollback version to display the VariantDisplay model instead --- src/Umbraco.Web/Editors/ContentController.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 85b42e59c3..73ad3ae81a 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1749,11 +1749,20 @@ namespace Umbraco.Web.Editors } [HttpGet] - public ContentItemDisplay GetRollbackVersion(int versionId) + public ContentVariantDisplay GetRollbackVersion(int versionId, string culture = null) { var version = Services.ContentService.GetVersion(versionId); var content = MapToDisplay(version); - return content; + + + //No culture set - so this is an invariant node - so just list me the first item in here + //TODO: Tripple check invariant nodes still has one item in the collection but with a language of null + if (culture == null) + { + return content.Variants.FirstOrDefault(); + } + + return content.Variants.FirstOrDefault(x => x.Language.IsoCode == culture); } [HttpPost] From ab34deb726cde40f94b59f866920190e2bbd7913 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 17 Oct 2018 20:37:15 +0200 Subject: [PATCH 16/52] add diff --- .../rollback/rollback.controller.js | 41 +++++-------------- 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js index 24fab8f30a..784cb7621f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js @@ -65,8 +65,8 @@ console.log("version", version); contentResource.getRollbackVersion(version.versionId) .then(function(data){ - console.log(data); - //createDiff(vm.currentVersion, data); + const previousVersion = data; + createDiff(vm.currentVersion, previousVersion); }); } @@ -78,7 +78,6 @@ return contentResource.getRollbackVersions(nodeId, culture) .then(function(data){ - console.log("new", data); vm.previousVersions = data; }); } @@ -92,42 +91,24 @@ */ function createDiff(currentVersion, previousVersion) { - // fake load version - vm.diff = {}; vm.diff.properties = []; - var oldVersion = { - "id": 2, - "name": "Foride", - "properties": [ - { - "alias": "headline", - "label": "Headline", - "value": "" - }, - { - "alias": "text", - "label": "Text", - "value": "This is my danish Content Test" - } - ] - }; - // find diff in name - vm.diff.name = JsDiff.diffWords(vm.currentVersion.name, oldVersion.name); + vm.diff.name = JsDiff.diffWords(vm.currentVersion.name, previousVersion.name); - // find diff in properties - angular.forEach(vm.currentVersion.properties, - function(newProperty, index){ - var oldProperty = oldVersion.properties[index]; + // extract all properties from the tabs and create new object for the diff + vm.currentVersion.tabs.forEach((tab, tabIndex) => { + tab.properties.forEach((property, propertyIndex) => { + var oldProperty = previousVersion.tabs[tabIndex].properties[propertyIndex]; var diffProperty = { - "alias": newProperty.alias, - "label": newProperty.label, - "diff": JsDiff.diffWords(newProperty.value, oldProperty.value) + "alias": property.alias, + "label": property.label, + "diff": JsDiff.diffWords(property.value, oldProperty.value) }; vm.diff.properties.push(diffProperty); }); + }); } From bdf474f111dcb3b559e14d55cb51518aa5efdbfe Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 18 Oct 2018 09:06:46 +0100 Subject: [PATCH 17/52] Typo in lazyload JS path for AuthUpgrade page --- src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml index 01afc9f2ec..3c79d5458c 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml @@ -72,7 +72,7 @@ @*And finally we can load in our angular app*@ - + From 3f82cd7677ebadbfa42d96d872dca3b5194316c7 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 18 Oct 2018 09:13:27 +0100 Subject: [PATCH 18/52] Update get rollback version to use a culture in the resource --- .../src/common/resources/content.resource.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js index 34a61cca91..bd64a2fdd8 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js @@ -835,7 +835,8 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { return umbRequestHelper.resourcePromise( $http.get( umbRequestHelper.getApiUrl("contentApiBaseUrl", "GetRollbackVersions", { - contentId: contentId, culture: culture + contentId: contentId, + culture: culture }) ), "Failed to get rollback versions for content item with id " + contentId @@ -853,21 +854,23 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { * * ##usage *
-          * contentResource.getRollbackVersion(versionId)
+          * contentResource.getRollbackVersion(versionId, culture)
           *    .then(function(version) {
           *        alert('its here!');
           *    });
           * 
* * @param {Int} versionId The version Id + * @param {Int} culture if provided, the results will be for this specific culture/variant * @returns {Promise} resourcePromise object containing the url. * */ - getRollbackVersion: function (versionId) { + getRollbackVersion: function (versionId, culture) { return umbRequestHelper.resourcePromise( $http.get( umbRequestHelper.getApiUrl("contentApiBaseUrl", "GetRollbackVersion", { - versionId: versionId + versionId: versionId, + culture: culture }) ), "Failed to get version for content item with id " + versionId From 813f3f8d84760e13fccbb9581b666aa41928f4ba Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 18 Oct 2018 10:21:13 +0200 Subject: [PATCH 19/52] a language should always be selected when a node has variants --- .../src/views/common/infiniteeditors/rollback/rollback.html | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html index 70dd189328..5fb618eb78 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html @@ -26,7 +26,6 @@ ng-model="vm.selectedLanguage" ng-options="variant as variant.language.name for variant in model.node.variants track by variant.language.culture" ng-change="vm.changeLanguage(vm.selectedLanguage)"> -
From fd0831618975583a712024fba25bf871920b4cfd Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 18 Oct 2018 11:10:27 +0200 Subject: [PATCH 20/52] wire up rollback button --- .../src/common/resources/content.resource.js | 40 ++++++++++++++++--- .../rollback/rollback.controller.js | 35 +++++++++++----- .../infiniteeditors/rollback/rollback.html | 3 +- 3 files changed, 62 insertions(+), 16 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js index bd64a2fdd8..71cbe3b8d7 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/content.resource.js @@ -828,7 +828,7 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { * * @param {Int} id Id of node * @param {Int} culture if provided, the results will be for this specific culture/variant - * @returns {Promise} resourcePromise object containing the url. + * @returns {Promise} resourcePromise object containing the versions * */ getRollbackVersions: function (contentId, culture) { @@ -843,7 +843,6 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { ); }, - /** * @ngdoc method * @name umbraco.resources.contentResource#getRollbackVersion @@ -862,7 +861,7 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { * * @param {Int} versionId The version Id * @param {Int} culture if provided, the results will be for this specific culture/variant - * @returns {Promise} resourcePromise object containing the url. + * @returns {Promise} resourcePromise object containing the version * */ getRollbackVersion: function (versionId, culture) { @@ -875,10 +874,41 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) { ), "Failed to get version for content item with id " + versionId ); + }, + + /** + * @ngdoc method + * @name umbraco.resources.contentResource#rollback + * @methodOf umbraco.resources.contentResource + * + * @description + * Roll backs a content item to a previous version + * + * ##usage + *
+          * contentResource.rollback(contentId, versionId, culture)
+          *    .then(function() {
+          *        alert('its here!');
+          *    });
+          * 
+ * + * @param {Int} id Id of node + * @param {Int} versionId The version Id + * @param {Int} culture if provided, the results will be for this specific culture/variant + * @returns {Promise} resourcePromise object + * + */ + rollback: function (contentId, versionId, culture) { + return umbRequestHelper.resourcePromise( + $http.post( + umbRequestHelper.getApiUrl("contentApiBaseUrl", "PostRollbackContent", { + contentId: contentId, versionId:versionId, culture:culture + }) + ), + "Failed to roll back content item with id " + contentId + ); } - - }; } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js index 784cb7621f..2aa628d5ef 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js @@ -65,8 +65,9 @@ console.log("version", version); contentResource.getRollbackVersion(version.versionId) .then(function(data){ - const previousVersion = data; - createDiff(vm.currentVersion, previousVersion); + vm.previousVersion = data; + vm.previousVersion.versionId = version.versionId; + createDiff(vm.currentVersion, vm.previousVersion); }); } @@ -82,10 +83,6 @@ }); } - function rollback() { - console.log("rollback"); - } - /** * This will load in a new version */ @@ -95,10 +92,10 @@ vm.diff.properties = []; // find diff in name - vm.diff.name = JsDiff.diffWords(vm.currentVersion.name, previousVersion.name); + vm.diff.name = JsDiff.diffWords(currentVersion.name, previousVersion.name); // extract all properties from the tabs and create new object for the diff - vm.currentVersion.tabs.forEach((tab, tabIndex) => { + currentVersion.tabs.forEach((tab, tabIndex) => { tab.properties.forEach((property, propertyIndex) => { var oldProperty = previousVersion.tabs[tabIndex].properties[propertyIndex]; var diffProperty = { @@ -112,9 +109,27 @@ } - function submit(model) { + function rollback() { + + vm.rollbackButtonState = "busy"; + + const nodeId = $scope.model.node.id; + const versionId = vm.previousVersion.versionId; + const culture = $scope.model.node.variants.length > 1 ? vm.currentVersion.language.culture : null; + + return contentResource.rollback(nodeId, versionId, culture) + .then(data => { + vm.rollbackButtonState = "success"; + submit(); + }, error => { + vm.rollbackButtonState = "error"; + }); + + } + + function submit() { if($scope.model.submit) { - $scope.model.submit(model); + $scope.model.submit($scope.model.submit); } } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html index 5fb618eb78..8c6c1f6de5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html @@ -91,8 +91,9 @@ + action="vm.rollback()"> From b2138d6376d3582baa175f819eefafc7bf7b43d8 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 18 Oct 2018 14:06:21 +0200 Subject: [PATCH 21/52] reload content after rollback --- .../directives/components/content/edit.controller.js | 11 +++++++++++ .../content/umbcontentnodeinfo.directive.js | 2 ++ 2 files changed, 13 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js index 98e02f3d55..6670a41ac4 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js @@ -103,6 +103,17 @@ loadContent(); } })); + + evts.push(eventsService.on("editors.content.reload", function (name, args) { + // if this content item uses the updated doc type we need to reload the content item + if(args && args.node && args.node.key === $scope.content.key) { + $scope.page.loading = true; + loadContent().then(function() { + $scope.page.loading = false; + }); + } + })); + } /** 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 327d99a8c6..e2292c50d5 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 @@ -106,6 +106,8 @@ var rollback = { node: scope.node, submit: function(model) { + const args = { node: scope.node }; + eventsService.emit("editors.content.reload", args); editorService.close(); }, close: function() { From a40a6e8f35185edfd1cb3bd422a090187969b12c Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 18 Oct 2018 13:13:11 +0100 Subject: [PATCH 22/52] WIP: Adds logging & audit message Fixes the filtering & dates to display in the version list --- src/Umbraco.Web/Editors/ContentController.cs | 77 ++++++++++++-------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index ad2734e8cf..b37bf82797 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1708,16 +1708,17 @@ namespace Umbraco.Web.Editors var rollbackVersions = new List(); //Return a list of all versions of a specific content node - var versions = Services.ContentService.GetVersions(contentId); - + //First item is our current item/state (cant rollback to ourselves) + var versions = Services.ContentService.GetVersions(contentId).Skip(1); + //Not all nodes are variants & thus culture can be null //Only filter the collection - //if(cultureName != null) - //{ - // versions = versions.Where(x => x.PublishDate == x.GetPublishDate(culture)); - //} + if (culture != null) + { + versions = versions.Where(x => x.UpdateDate == x.GetUpdateDate(culture)); + } - foreach(var version in versions) + foreach (var version in versions) { var rollbackVersion = new RollbackVersion(); @@ -1725,22 +1726,12 @@ namespace Umbraco.Web.Editors rollbackVersion.VersionId = version.VersionId; //Date of version - var cultureDate = version.GetPublishDate(culture); - if (cultureDate.HasValue) - { - rollbackVersion.VersionDate = cultureDate.Value; - } - else - { - rollbackVersion.VersionDate = version.UpdateDate; - } - - //Name of publisher - //TODO: Reviewer would this extra info be expensive? - var publisherId = version.PublisherId; - var userId = version.PublisherId.HasValue ? version.PublisherId.Value : version.WriterId; - var publisher = Services.UserService.GetUserById(userId); - rollbackVersion.VersionAuthorName = publisher.Name; + rollbackVersion.VersionDate = version.UpdateDate; + + //Name of writer/publisher/user + var writerId = version.WriterId; + var user = Services.UserService.GetUserById(writerId); + rollbackVersion.VersionAuthorName = user.Name; rollbackVersions.Add(rollbackVersion); } @@ -1768,8 +1759,10 @@ namespace Umbraco.Web.Editors [HttpPost] public HttpResponseMessage PostRollbackContent(int contentId, int versionId, string culture = "*") { - //TODO: Do we log something - so there is a trail in the logs - //Of who performed the rollback of what document, time + var userId = Security.GetUserId().ResultOr(0); + + Logger.Info("User ID {UserId} is attempting to rollback content '{ContentId}' to version '{VersionId}'", userId, contentId, versionId); + Services.AuditService.Add(AuditType.RollBack, "YO YO YO IM ROLLING BACK", userId, contentId); //Get the current copy of the node var content = Services.ContentService.GetById(contentId); @@ -1778,16 +1771,38 @@ namespace Umbraco.Web.Editors var version = Services.ContentService.GetVersion(versionId); //Copy the changes from the version - content.CopyFrom(version); - - //Save & Publish the update - var publishResult = Services.ContentService.SaveAndPublish(content, culture, Security.GetUserId().ResultOr(0)); - if (publishResult.Success == false) + content.CopyFrom(version, culture); + + //Save the update + var saveResult = Services.ContentService.Save(content, userId); + if(saveResult.Success == false) { + Logger.Error("Unable to rollback content '{ContentId}' to version '{VersionId}'", contentId, versionId); + var notificationModel = new SimpleNotificationModel(); - AddMessageForPublishStatus(publishResult, notificationModel); + + switch (saveResult.Result) + { + case OperationResultType.Failed: + case OperationResultType.FailedCannot: + case OperationResultType.FailedExceptionThrown: + case OperationResultType.NoOperation: + default: + notificationModel.AddErrorNotification( + Services.TextService.Localize("speechBubbles/operationFailedHeader"), + null); //TODO: There is no specific failed to save error message AFAIK + break; + case OperationResultType.FailedCancelledByEvent: + notificationModel.AddErrorNotification( + Services.TextService.Localize("speechBubbles/operationCancelledHeader"), + Services.TextService.Localize("speechBubbles/operationCancelledText")); + break; + } + return Request.CreateValidationErrorResponse(notificationModel); } + + Logger.Info("User ID {UserId} rolled back content '{ContentId}' to version '{VersionId}'", userId, contentId, versionId); //return ok return Request.CreateResponse(HttpStatusCode.OK); From 510666cd7e7b35ae7852fd3d033eda3443e87353 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 18 Oct 2018 14:16:50 +0200 Subject: [PATCH 23/52] ContentService.GetPagedChildren is broken? --- .../Services/ContentServiceTests.cs | 102 ++++++++++++++++++ .../TestHelpers/TestWithDatabaseBase.cs | 2 + 2 files changed, 104 insertions(+) diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index a82ccd2a0e..ef34f4bc24 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -25,6 +25,7 @@ using Umbraco.Core.Services.Implement; using Umbraco.Tests.Testing; using Umbraco.Web.PropertyEditors; using System.Reflection; +using Umbraco.Core.Persistence.DatabaseModelDefinitions; namespace Umbraco.Tests.Services { @@ -2744,6 +2745,107 @@ namespace Umbraco.Tests.Services } } + [Test] + public void Can_Get_Paged_Children_WithFilterAndOrder() + { + var languageService = ServiceContext.LocalizationService; + + var langUk = new Language("en-UK") { IsDefault = true }; + var langFr = new Language("fr-FR"); + var langDa = new Language("da-DK"); + + languageService.Save(langFr); + languageService.Save(langUk); + languageService.Save(langDa); + + var contentTypeService = ServiceContext.ContentTypeService; + + var contentType = contentTypeService.Get("umbTextpage"); + contentType.Variations = ContentVariation.Culture; + contentTypeService.Save(contentType); + + var contentService = ServiceContext.ContentService; + + var o = new[] { 2, 1, 3, 0, 4 }; // randomly different + for (var i = 0; i < 5; i++) + { + var contentA = new Content(null, -1, contentType); + contentA.SetCultureName("contentA" + i + "uk", langUk.IsoCode); + contentA.SetCultureName("contentA" + o[i] + "fr", langFr.IsoCode); + contentA.SetCultureName("contentX" + i + "da", langDa.IsoCode); + contentService.Save(contentA); + + var contentB = new Content(null, -1, contentType); + contentB.SetCultureName("contentB" + i + "uk", langUk.IsoCode); + contentB.SetCultureName("contentB" + o[i] + "fr", langFr.IsoCode); + contentB.SetCultureName("contentX" + i + "da", langDa.IsoCode); + contentService.Save(contentB); + } + + // get all + var list = contentService.GetPagedChildren(-1, 0, 100, out var total).ToList(); + + Console.WriteLine("ALL"); + WriteList(list); + + // 10 items (there's already a Home content in there...) + Assert.AreEqual(11, total); + Assert.AreEqual(11, list.Count); + + // filter + list = contentService.GetPagedChildren(-1, 0, 100, out total, + SqlContext.Query().Where(x => x.Name.Contains("contentX")), + Ordering.By("name", culture: langFr.IsoCode)).ToList(); + + Assert.AreEqual(0, total); + Assert.AreEqual(0, list.Count); + + // filter + list = contentService.GetPagedChildren(-1, 0, 100, out total, + SqlContext.Query().Where(x => x.Name.Contains("contentX")), + Ordering.By("name", culture: langDa.IsoCode)).ToList(); + + Console.WriteLine("FILTER BY NAME da:'contentX'"); + WriteList(list); + + Assert.AreEqual(10, total); + Assert.AreEqual(10, list.Count); + + // filter + list = contentService.GetPagedChildren(-1, 0, 100, out total, + SqlContext.Query().Where(x => x.Name.Contains("contentA")), + Ordering.By("name", culture: langFr.IsoCode)).ToList(); + + Console.WriteLine("FILTER BY NAME fr:'contentA', ORDER ASC"); + WriteList(list); + + Assert.AreEqual(5, total); + Assert.AreEqual(5, list.Count); + + for (var i = 0; i < 5; i++) + Assert.AreEqual("contentA" + i + "fr", list[i].GetCultureName(langFr.IsoCode)); + + list = contentService.GetPagedChildren(-1, 0, 100, out total, + SqlContext.Query().Where(x => x.Name.Contains("contentA")), + Ordering.By("name", direction: Direction.Descending, culture: langFr.IsoCode)).ToList(); + + Console.WriteLine("FILTER BY NAME fr:'contentA', ORDER DESC"); + WriteList(list); + + Assert.AreEqual(5, total); + Assert.AreEqual(5, list.Count); + + for (var i = 0; i < 5; i++) + Assert.AreEqual("contentA" + (4-i) + "fr", list[i].GetCultureName(langFr.IsoCode)); + } + + private void WriteList(List list) + { + foreach (var content in list) + Console.WriteLine("[{0}] {1} {2} {3} {4}", content.Id, content.Name, content.GetCultureName("en-UK"), content.GetCultureName("fr-FR"), content.GetCultureName("da-DK")); + Console.WriteLine("-"); + } + [Test] public void Can_SaveRead_Variations() { diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index 21f1ce82b2..6b52137542 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -64,6 +64,8 @@ namespace Umbraco.Tests.TestHelpers internal ScopeProvider ScopeProvider => Current.ScopeProvider as ScopeProvider; + protected ISqlContext SqlContext => Container.GetInstance(); + public override void SetUp() { base.SetUp(); From 2b83b44c9c48f7f8ec1a95502a46a24a77c0719c Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 18 Oct 2018 14:16:54 +0200 Subject: [PATCH 24/52] Fix ContentService.GetPagedChildren --- .../Persistence/NPocoSqlExtensions.cs | 11 ++-- .../Implement/ContentRepositoryBase.cs | 9 +-- .../Implement/DocumentRepository.cs | 55 ++++++++-------- .../Repositories/Implement/MediaRepository.cs | 9 ++- .../Implement/MemberRepository.cs | 12 ++-- .../Persistence/SqlContextExtensions.cs | 65 ++++++++++++++----- 6 files changed, 101 insertions(+), 60 deletions(-) diff --git a/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs b/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs index 7f6eb72a25..a5ab62d25f 100644 --- a/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs +++ b/src/Umbraco.Core/Persistence/NPocoSqlExtensions.cs @@ -73,7 +73,7 @@ namespace Umbraco.Core.Persistence /// The Sql statement. public static Sql Where(this Sql sql, Expression> predicate, string alias = null) { - var (s, a) = sql.SqlContext.Visit(predicate, alias); + var (s, a) = sql.SqlContext.VisitDto(predicate, alias); return sql.Where(s, a); } @@ -89,7 +89,7 @@ namespace Umbraco.Core.Persistence /// The Sql statement. public static Sql Where(this Sql sql, Expression> predicate, string alias1 = null, string alias2 = null) { - var (s, a) = sql.SqlContext.Visit(predicate, alias1, alias2); + var (s, a) = sql.SqlContext.VisitDto(predicate, alias1, alias2); return sql.Where(s, a); } @@ -321,9 +321,9 @@ namespace Umbraco.Core.Persistence /// Appends an ORDER BY DESC clause to the Sql statement. /// /// The Sql statement. - /// Expression specifying the fields. + /// Fields. /// The Sql statement. - public static Sql OrderByDescending(this Sql sql, params object[] fields) + public static Sql OrderByDescending(this Sql sql, params string[] fields) { return sql.Append("ORDER BY " + string.Join(", ", fields.Select(x => x + " DESC"))); } @@ -664,7 +664,7 @@ namespace Umbraco.Core.Persistence /// Adds columns to a SELECT Sql statement. /// /// The origin sql. - /// Expression indicating the column to select. + /// Columns to select. /// The Sql statement. public static Sql AndSelect(this Sql sql, params string[] fields) { @@ -688,7 +688,6 @@ namespace Umbraco.Core.Persistence return sql.Append(", " + string.Join(", ", sql.GetColumns(columnExpressions: fields))); } - /// /// Adds columns to a SELECT Sql statement. /// diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs index 41f0f16225..34bc3713f3 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentRepositoryBase.cs @@ -252,8 +252,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement // if we do not do this then we end up with issues where we are ordering by a field that has duplicate values (i.e. the 'text' column // is empty for many nodes) - see: http://issues.umbraco.org/issue/U4-8831 - var dbfield = GetQuotedFieldName("umbracoNode", "id"); - (dbfield, _) = SqlContext.Visit(x => x.NodeId); // fixme?! + var (dbfield, _) = SqlContext.VisitDto(x => x.NodeId); if (ordering.IsCustomField || !ordering.OrderBy.InvariantEquals("id")) { psql.OrderBy(GetAliasedField(dbfield, sql)); // fixme why aliased? @@ -262,7 +261,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement // create prepared sql // ensure it's single-line as NPoco PagingHelper has issues with multi-lines psql = Sql(psql.SQL.ToSingleLine(), psql.Arguments); - // replace the magic culture parameter (see DocumentRepository.GetBaseQuery()) if (!ordering.Culture.IsNullOrWhiteSpace()) @@ -353,6 +351,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement if (ordering.Culture.IsNullOrWhiteSpace()) return GetAliasedField(SqlSyntax.GetFieldName(x => x.Text), sql); + // "variantName" alias is defined in DocumentRepository.GetBaseQuery + // fixme - what if it is NOT a document but a ... media or whatever? + // previously, we inserted the join+select *here* so we were sure to have it, + // but now that's not the case anymore! return "variantName"; } @@ -433,7 +435,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement // sort and filter sql = PreparePageSql(sql, filter, ordering); - // get a page of DTOs and the total count var pagedResult = Database.Page(pageIndex + 1, pageSize, sql); totalRecords = Convert.ToInt32(pagedResult.TotalItems); diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs index 3cb61ad8e1..df389c738a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs @@ -95,6 +95,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement return GetBaseQuery(queryType, true); } + // gets the COALESCE expression for variant/invariant name + private string VariantNameSqlExpression + => SqlContext.VisitDto((ccv, node) => ccv.Name ?? node.Text, "ccv").Sql; + protected virtual Sql GetBaseQuery(QueryType queryType, bool current) { var sql = SqlContext.Sql(); @@ -116,7 +120,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement r1.Select(documentVersionDto => documentVersionDto.ContentVersionDto)) .Select(documentDto => documentDto.PublishedVersionDto, "pdv", r1 => r1.Select(documentVersionDto => documentVersionDto.ContentVersionDto, "pcv"))) - .AndSelect(SqlContext.Visit((ccv, node) => ccv.Name ?? node.Text, "ccv").Sql + " AS variantName"); + + // select the variant name, coalesce to the invariant name, as "variantName" + .AndSelect(VariantNameSqlExpression + " AS variantName"); break; } @@ -135,18 +141,17 @@ namespace Umbraco.Core.Persistence.Repositories.Implement .LeftJoin(nested => nested.InnerJoin("pdv") .On((left, right) => left.Id == right.Id && right.Published, "pcv", "pdv"), "pcv") - .On((left, right) => left.NodeId == right.NodeId, aliasRight: "pcv"); + .On((left, right) => left.NodeId == right.NodeId, aliasRight: "pcv") - //the magic [[[ISOCODE]]] will be replaced in ContentRepositoryBase.GetPage() by the current Iso code - sql + // left join on optional culture variation + //the magic "[[[ISOCODE]]]" parameter value will be replaced in ContentRepositoryBase.GetPage() by the actual ISO code .LeftJoin(nested => nested.InnerJoin("lang").On((ccv, lang) => ccv.LanguageId == lang.Id && lang.IsoCode == "[[[ISOCODE]]]", "ccv", "lang"), "ccv") - .On((version, ccv) => version.Id == ccv.VersionId, "pcv", "ccv"); + .On((version, ccv) => version.Id == ccv.VersionId, aliasRight: "ccv"); sql .Where(x => x.NodeObjectType == NodeObjectTypeId); - // this would ensure we don't get the published version - keep for reference //sql // .WhereAny( @@ -157,7 +162,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement if (current) sql.Where(x => x.Current); // always get the current version - return sql; } @@ -246,7 +250,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement // however, it's not just so we have access to AddingEntity // there are tons of things at the end of the methods, that can only work with a true Content // and basically, the repository requires a Content, not an IContent - var content = (Content)entity; + var content = (Content) entity; content.AddingEntity(); var publishing = content.PublishedState == PublishedState.Publishing; @@ -420,7 +424,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement // however, it's not just so we have access to AddingEntity // there are tons of things at the end of the methods, that can only work with a true Content // and basically, the repository requires a Content, not an IContent - var content = (Content)entity; + var content = (Content) entity; // check if we need to make any database changes at all if ((content.PublishedState == PublishedState.Published || content.PublishedState == PublishedState.Unpublished) && !content.IsEntityDirty() && !content.IsAnyUserPropertyDirty()) @@ -707,30 +711,27 @@ namespace Umbraco.Core.Persistence.Repositories.Implement { Sql filterSql = null; - // Here we create a default where clause from a temp IContent which will look in the contentVersion table for the content name - // if we are searching in a list view that contains variants, we want to look in the contentVersionCultureVariation table instead. - // The resulting clause will be used in the foreach below to compare against the original clause that comes from the "filter" and if they are the same - // we know that we are searching a list view and the proper where clause will be replaced to look in contentVersionCultureVariation table for the names. - var temp = Query().Where(x => x.Name.Contains("foo")); - var clause = temp.GetWhereClauses().First().Item1.Split(' ')[0]; - + // if we have a filter, map its clauses to an Sql statement if (filter != null) { + // if the clause works on "name", we need to swap the field and use the variantName instead, + // so that querying also works on variant content (for instance when searching a listview). + + // figure out how the "name" field is going to look like - so we can look for it + var nameField = SqlContext.VisitModelField(x => x.Name); + filterSql = Sql(); foreach (var filterClause in filter.GetWhereClauses()) { - // fixme - is this the right way of doing it??? + var clauseSql = filterClause.Item1; + var clauseArgs = filterClause.Item2; - // - var where = filterClause.Item1.Split(' ')[0] == clause - // normally, this would be the field alias (variantName) of the coalesce result between ContentVersionCulture and NodeDto names, however - // you can't refer to field alias in a WHERE clause so we have to put the coalesce calculation instead which refers to the original field - ? SqlContext.Visit((ccv, node) => ccv.Name ?? node.Text, "ccv").Sql - : filterClause.Item1; + // replace the name field + // we cannot reference an aliased field in a WHERE clause, so have to repeat the expression here + clauseSql = clauseSql.Replace(nameField, VariantNameSqlExpression); - filterSql.Append( - where.Contains("COALESCE") ? $"AND upper({where}) LIKE upper(@0)" : $"AND ({where})", - filterClause.Item2); + // append the clause + filterSql.Append($"AND ({clauseSql})", clauseArgs); } } @@ -928,7 +929,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement var cached = IsolatedCache.GetCacheItem(RepositoryCacheKeys.GetKey(dto.NodeId)); if (cached != null && cached.VersionId == dto.DocumentVersionDto.ContentVersionDto.Id) { - content[i] = (Content)cached; + content[i] = (Content) cached; continue; } } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/MediaRepository.cs index 2390ce9a7b..dbfdc8e980 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/MediaRepository.cs @@ -8,12 +8,12 @@ using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Exceptions; using Umbraco.Core.Logging; using Umbraco.Core.Models; -using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.Persistence.Factories; using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Scoping; using Umbraco.Core.Services; +using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics; namespace Umbraco.Core.Persistence.Repositories.Implement { @@ -100,7 +100,12 @@ namespace Umbraco.Core.Persistence.Repositories.Implement case QueryType.Many: sql = sql.Select(r => r.Select(x => x.NodeDto) - .Select(x => x.ContentVersionDto)); + .Select(x => x.ContentVersionDto)) + + // ContentRepositoryBase expects a variantName field to order by name + // for now, just return the plain invariant node name + // fixme media should support variants !! + .AndSelect(x => Alias(x.Text, "variantName")); break; } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberRepository.cs index 84ef154ae8..fd79b231de 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberRepository.cs @@ -6,12 +6,12 @@ using NPoco; using Umbraco.Core.Cache; using Umbraco.Core.Logging; using Umbraco.Core.Models; -using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Dtos; using Umbraco.Core.Persistence.Factories; using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Scoping; using Umbraco.Core.Services; +using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics; namespace Umbraco.Core.Persistence.Repositories.Implement { @@ -114,9 +114,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement case QueryType.Single: case QueryType.Many: sql = sql.Select(r => - r.Select(x => x.ContentVersionDto) - .Select(x => x.ContentDto, r1 => - r1.Select(x => x.NodeDto))); + r.Select(x => x.ContentVersionDto) + .Select(x => x.ContentDto, r1 => + r1.Select(x => x.NodeDto))) + + // ContentRepositoryBase expects a variantName field to order by name + // so get it here, though for members it's just the plain node name + .AndSelect(x => Alias(x.Text, "variantName")); break; } diff --git a/src/Umbraco.Core/Persistence/SqlContextExtensions.cs b/src/Umbraco.Core/Persistence/SqlContextExtensions.cs index e28816b6a4..249e2cafd0 100644 --- a/src/Umbraco.Core/Persistence/SqlContextExtensions.cs +++ b/src/Umbraco.Core/Persistence/SqlContextExtensions.cs @@ -17,11 +17,11 @@ namespace Umbraco.Core.Persistence /// An expression to visit. /// An optional table alias. /// A SQL statement, and arguments, corresponding to the expression. - public static (string Sql, object[] Args) Visit(this ISqlContext sqlContext, Expression> expression, string alias = null) + public static (string Sql, object[] Args) VisitDto(this ISqlContext sqlContext, Expression> expression, string alias = null) { - var expresionist = new PocoToSqlExpressionVisitor(sqlContext, alias); - var visited = expresionist.Visit(expression); - return (visited, expresionist.GetSqlParameters()); + var visitor = new PocoToSqlExpressionVisitor(sqlContext, alias); + var visited = visitor.Visit(expression); + return (visited, visitor.GetSqlParameters()); } /// @@ -33,11 +33,11 @@ namespace Umbraco.Core.Persistence /// An expression to visit. /// An optional table alias. /// A SQL statement, and arguments, corresponding to the expression. - public static (string Sql, object[] Args) Visit(this ISqlContext sqlContext, Expression> expression, string alias = null) + public static (string Sql, object[] Args) VisitDto(this ISqlContext sqlContext, Expression> expression, string alias = null) { - var expresionist = new PocoToSqlExpressionVisitor(sqlContext, alias); - var visited = expresionist.Visit(expression); - return (visited, expresionist.GetSqlParameters()); + var visitor = new PocoToSqlExpressionVisitor(sqlContext, alias); + var visited = visitor.Visit(expression); + return (visited, visitor.GetSqlParameters()); } /// @@ -50,11 +50,11 @@ namespace Umbraco.Core.Persistence /// An optional table alias for the first DTO. /// An optional table alias for the second DTO. /// A SQL statement, and arguments, corresponding to the expression. - public static (string Sql, object[] Args) Visit(this ISqlContext sqlContext, Expression> expression, string alias1 = null, string alias2 = null) + public static (string Sql, object[] Args) VisitDto(this ISqlContext sqlContext, Expression> expression, string alias1 = null, string alias2 = null) { - var expresionist = new PocoToSqlExpressionVisitor(sqlContext, alias1, alias2); - var visited = expresionist.Visit(expression); - return (visited, expresionist.GetSqlParameters()); + var visitor = new PocoToSqlExpressionVisitor(sqlContext, alias1, alias2); + var visited = visitor.Visit(expression); + return (visited, visitor.GetSqlParameters()); } /// @@ -68,11 +68,42 @@ namespace Umbraco.Core.Persistence /// An optional table alias for the first DTO. /// An optional table alias for the second DTO. /// A SQL statement, and arguments, corresponding to the expression. - public static (string Sql, object[] Args) Visit(this ISqlContext sqlContext, Expression> expression, string alias1 = null, string alias2 = null) + public static (string Sql, object[] Args) VisitDto(this ISqlContext sqlContext, Expression> expression, string alias1 = null, string alias2 = null) { - var expresionist = new PocoToSqlExpressionVisitor(sqlContext, alias1, alias2); - var visited = expresionist.Visit(expression); - return (visited, expresionist.GetSqlParameters()); + var visitor = new PocoToSqlExpressionVisitor(sqlContext, alias1, alias2); + var visited = visitor.Visit(expression); + return (visited, visitor.GetSqlParameters()); + } + + /// + /// Visit a model expression. + /// + /// The type of the model. + /// An . + /// An expression to visit. + /// A SQL statement, and arguments, corresponding to the expression. + public static (string Sql, object[] Args) VisitModel(this ISqlContext sqlContext, Expression> expression) + { + var visitor = new ModelToSqlExpressionVisitor(sqlContext.SqlSyntax, sqlContext.Mappers); + var visited = visitor.Visit(expression); + return (visited, visitor.GetSqlParameters()); + } + + /// + /// Visit a model expression representing a field. + /// + /// The type of the model. + /// An . + /// An expression to visit, representing a field. + /// The name of the field. + public static string VisitModelField(this ISqlContext sqlContext, Expression> field) + { + var (sql, _) = sqlContext.VisitModel(field); + + // going to return " = @0" + // take the first part only + var pos = sql.IndexOf(' '); + return sql.Substring(0, pos); } } -} \ No newline at end of file +} From a12d736b6bb61e2d837562d93b06dc1a8e8aec3a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 18 Oct 2018 14:56:00 +0200 Subject: [PATCH 25/52] show user in version dropdown --- .../common/infiniteeditors/rollback/rollback.controller.js | 5 ++++- .../src/views/common/infiniteeditors/rollback/rollback.html | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js index 2aa628d5ef..f96c1f6a3d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js @@ -79,7 +79,10 @@ return contentResource.getRollbackVersions(nodeId, culture) .then(function(data){ - vm.previousVersions = data; + vm.previousVersions = data.map(version => { + version.displayValue = version.versionDate + " - " + version.versionAuthorName; + return version; + }); }); } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html index 8c6c1f6de5..5faba3a3ef 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html @@ -38,7 +38,7 @@ From 09a744370140c36c5acbc578707100e504013550 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 18 Oct 2018 15:16:37 +0200 Subject: [PATCH 26/52] dont show diff if a versionId is not set --- .../rollback/rollback.controller.js | 21 ++++++++++++------- .../content/umb-content-node-info.html | 3 ++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js index f96c1f6a3d..63672879b0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js @@ -62,14 +62,21 @@ } function changeVersion(version) { - console.log("version", version); - contentResource.getRollbackVersion(version.versionId) - .then(function(data){ - vm.previousVersion = data; - vm.previousVersion.versionId = version.versionId; - createDiff(vm.currentVersion, vm.previousVersion); - }); + if(version && version.versionId) { + + const culture = $scope.model.node.variants.length > 1 ? vm.currentVersion.language.culture : null; + + contentResource.getRollbackVersion(version.versionId, culture) + .then(function(data){ + vm.previousVersion = data; + vm.previousVersion.versionId = version.versionId; + createDiff(vm.currentVersion, vm.previousVersion); + }); + + } else { + vm.diff = null; + } } function getVersions() { 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 77a7161762..d8bc08491a 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 @@ -49,7 +49,8 @@ button-style="outline" action="openRollback()" label-key="actions_rollback" - size="xs"> + size="xs" + add-ellipsis="true"> From 6f7d0c3a45f4025534731d805b2259460ac85393 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 18 Oct 2018 14:24:32 +0100 Subject: [PATCH 27/52] Move logic out of controller into a Rollback method in the service level --- src/Umbraco.Core/Services/IContentService.cs | 13 +++ .../Services/Implement/ContentService.cs | 42 ++++++++++ src/Umbraco.Web/Editors/ContentController.cs | 83 +++++++------------ 3 files changed, 84 insertions(+), 54 deletions(-) diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index 022bee8b41..3a0f920d48 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -461,5 +461,18 @@ namespace Umbraco.Core.Services IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = 0); #endregion + + #region Rollback + + /// + /// Rolls back the content to a specific version. + /// + /// The id of the content node + /// The version ID to rollback to + /// An optional culture - specifying a culture will only rollback the culture content + /// The user ID who is performing the rollback + OperationResult Rollback(int id, int versionId, string culture = "*", int userId = 0); + + #endregion } } diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index a849813b13..d7f11a3e2f 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -2490,5 +2490,47 @@ namespace Umbraco.Core.Services.Implement } #endregion + + #region Rollback + + public OperationResult Rollback(int id, int versionId, string culture = "*", int userId = 0) + { + var evtMsgs = EventMessagesFactory.Get(); + + //Get the current copy of the node + var content = GetById(id); + + //Get the version + var version = GetVersion(versionId); + + //Good ole null checks + if (content == null || version == null) + { + return new OperationResult(OperationResultType.FailedCannot, evtMsgs); + } + + //Copy the changes from the version + content.CopyFrom(version, culture); + + //Save the content for the rollback + var rollbackSaveResult = Save(content, userId); + + //Depending on the save result - is what we log & audit along with what we return + if(rollbackSaveResult.Success == false) + { + //Log the error/warning + Logger.Error("User '{UserId}' was unable to rollback content '{ContentId}' to version '{VersionId}'", userId, id, versionId); + } + else + { + //Logging & Audit message + Logger.Error("User '{UserId}' rolled back content '{ContentId}' to version '{VersionId}'", userId, id, versionId); + Audit(AuditType.RollBack, $"Content '{content.Name}' was rolled back to version '{versionId}'", userId, id); + } + + return rollbackSaveResult; + } + + #endregion } } diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index b37bf82797..be4801ae61 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1707,9 +1707,8 @@ namespace Umbraco.Web.Editors { var rollbackVersions = new List(); - //Return a list of all versions of a specific content node - //First item is our current item/state (cant rollback to ourselves) - var versions = Services.ContentService.GetVersions(contentId).Skip(1); + //Return a list of all versions of a specific content node + var versions = Services.ContentService.GetVersions(contentId); //Not all nodes are variants & thus culture can be null //Only filter the collection @@ -1718,6 +1717,9 @@ namespace Umbraco.Web.Editors versions = versions.Where(x => x.UpdateDate == x.GetUpdateDate(culture)); } + //First item is our current item/state (cant rollback to ourselves) + versions = versions.Skip(1); + foreach (var version in versions) { var rollbackVersion = new RollbackVersion(); @@ -1744,68 +1746,41 @@ namespace Umbraco.Web.Editors { var version = Services.ContentService.GetVersion(versionId); var content = MapToDisplay(version); - - - //No culture set - so this is an invariant node - so just list me the first item in here - //TODO: Tripple check invariant nodes still has one item in the collection but with a language of null - if (culture == null) - { - return content.Variants.FirstOrDefault(); - } - - return content.Variants.FirstOrDefault(x => x.Language.IsoCode == culture); + + return culture == null + ? content.Variants.FirstOrDefault() //No culture set - so this is an invariant node - so just list me the first item in here + : content.Variants.FirstOrDefault(x => x.Language.IsoCode == culture); } [HttpPost] public HttpResponseMessage PostRollbackContent(int contentId, int versionId, string culture = "*") { - var userId = Security.GetUserId().ResultOr(0); + var rollbackResult = Services.ContentService.Rollback(contentId, versionId, culture, Security.GetUserId().ResultOr(0)); - Logger.Info("User ID {UserId} is attempting to rollback content '{ContentId}' to version '{VersionId}'", userId, contentId, versionId); - Services.AuditService.Add(AuditType.RollBack, "YO YO YO IM ROLLING BACK", userId, contentId); + if (rollbackResult.Success) + return Request.CreateResponse(HttpStatusCode.OK); - //Get the current copy of the node - var content = Services.ContentService.GetById(contentId); + var notificationModel = new SimpleNotificationModel(); - //Get the version - var version = Services.ContentService.GetVersion(versionId); - - //Copy the changes from the version - content.CopyFrom(version, culture); - - //Save the update - var saveResult = Services.ContentService.Save(content, userId); - if(saveResult.Success == false) + switch (rollbackResult.Result) { - Logger.Error("Unable to rollback content '{ContentId}' to version '{VersionId}'", contentId, versionId); - - var notificationModel = new SimpleNotificationModel(); - - switch (saveResult.Result) - { - case OperationResultType.Failed: - case OperationResultType.FailedCannot: - case OperationResultType.FailedExceptionThrown: - case OperationResultType.NoOperation: - default: - notificationModel.AddErrorNotification( - Services.TextService.Localize("speechBubbles/operationFailedHeader"), - null); //TODO: There is no specific failed to save error message AFAIK - break; - case OperationResultType.FailedCancelledByEvent: - notificationModel.AddErrorNotification( - Services.TextService.Localize("speechBubbles/operationCancelledHeader"), - Services.TextService.Localize("speechBubbles/operationCancelledText")); - break; - } - - return Request.CreateValidationErrorResponse(notificationModel); + case OperationResultType.Failed: + case OperationResultType.FailedCannot: + case OperationResultType.FailedExceptionThrown: + case OperationResultType.NoOperation: + default: + notificationModel.AddErrorNotification( + Services.TextService.Localize("speechBubbles/operationFailedHeader"), + null); //TODO: There is no specific failed to save error message AFAIK + break; + case OperationResultType.FailedCancelledByEvent: + notificationModel.AddErrorNotification( + Services.TextService.Localize("speechBubbles/operationCancelledHeader"), + Services.TextService.Localize("speechBubbles/operationCancelledText")); + break; } - - Logger.Info("User ID {UserId} rolled back content '{ContentId}' to version '{VersionId}'", userId, contentId, versionId); - //return ok - return Request.CreateResponse(HttpStatusCode.OK); + return Request.CreateValidationErrorResponse(notificationModel); } } } From 0f528a7a8903cdc744ac28b81621e6fe70f66c8e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 18 Oct 2018 15:25:17 +0200 Subject: [PATCH 28/52] disable roll back button when no version is selected --- .../common/infiniteeditors/rollback/rollback.controller.js | 3 +++ .../src/views/common/infiniteeditors/rollback/rollback.html | 1 + 2 files changed, 4 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js index 63672879b0..eac4fab8a7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js @@ -19,6 +19,7 @@ vm.variantVersions = []; vm.diff = null; vm.currentVersion = null; + vm.rollbackButtonDisabled = true; // find the current version for invariant nodes if($scope.model.node.variants.length === 1) { @@ -72,10 +73,12 @@ vm.previousVersion = data; vm.previousVersion.versionId = version.versionId; createDiff(vm.currentVersion, vm.previousVersion); + vm.rollbackButtonDisabled = false; }); } else { vm.diff = null; + vm.rollbackButtonDisabled = true; } } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html index 5faba3a3ef..6758f1df9b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html @@ -93,6 +93,7 @@ button-style="success" state="vm.rollbackButtonState" label-key="actions_rollback" + disabled="vm.rollbackButtonDisabled" action="vm.rollback()"> From 321313f134e34df9956994707ebcc4923bacf74b Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 18 Oct 2018 14:32:44 +0100 Subject: [PATCH 29/52] Remove rollback .aspx dialog --- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 1 - .../Umbraco/dialogs/rollBack.aspx | 98 ------------------- 2 files changed, 99 deletions(-) delete mode 100644 src/Umbraco.Web.UI/Umbraco/dialogs/rollBack.aspx diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index de52021220..d18dab1987 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -348,7 +348,6 @@ - diff --git a/src/Umbraco.Web.UI/Umbraco/dialogs/rollBack.aspx b/src/Umbraco.Web.UI/Umbraco/dialogs/rollBack.aspx deleted file mode 100644 index 84b2cc5cb8..0000000000 --- a/src/Umbraco.Web.UI/Umbraco/dialogs/rollBack.aspx +++ /dev/null @@ -1,98 +0,0 @@ -<%@ Page Language="c#" MasterPageFile="../masterpages/umbracoDialog.Master"AutoEventWireup="True" Inherits="umbraco.presentation.dialogs.rollBack" %> - -<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> -<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" Assembly="Umbraco.Web" %> - - - - - - - - -
- - - - - - - - () - - - - - - - - Diff - Html - - - - - - -
-
-

- -

-
- - - -
-
-
-
- - -
From 1efe90ba1d362f7be6766f8c764f06f5c22c44e6 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 18 Oct 2018 14:54:29 +0100 Subject: [PATCH 30/52] More rollback .aspx dialogs removed --- src/Umbraco.Web/Umbraco.Web.csproj | 9 - .../umbraco/dialogs/rollBack.aspx | 99 ----------- .../umbraco/dialogs/rollBack.aspx.cs | 156 ------------------ .../umbraco/dialogs/rollBack.aspx.designer.cs | 150 ----------------- 4 files changed, 414 deletions(-) delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.designer.cs diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 5235728814..d87ae5dd1c 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1312,12 +1312,6 @@ editPackage.aspx - - rollBack.aspx - - - rollBack.aspx - @@ -1402,9 +1396,6 @@ ASPXCodeBehind - - ASPXCodeBehind - diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx deleted file mode 100644 index 88f106d269..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx +++ /dev/null @@ -1,99 +0,0 @@ -<%@ Page Language="c#" CodeBehind="rollBack.aspx.cs" MasterPageFile="../masterpages/umbracoDialog.Master" AutoEventWireup="True" Inherits="umbraco.presentation.dialogs.rollBack" %> - -<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> -<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" %> - - - - - - - - -
- - - - - - - - () - - - - - - - - Diff - Html - - - - - - -
-
-

- -

-
- - - -
-
-
-
- - -
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs deleted file mode 100644 index 54f2871149..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs +++ /dev/null @@ -1,156 +0,0 @@ -//TODO: REbuild this in angular and then remove - -//using System; -//using System.Collections; -//using System.ComponentModel; -//using System.Data; -//using System.Drawing; -//using System.Linq; -//using System.Web; -//using System.Web.SessionState; -//using System.Web.UI; -//using System.Web.UI.WebControls; -//using System.Web.UI.HtmlControls; -// -//using umbraco.cms.businesslogic.web; -//using umbraco.cms.businesslogic.property; - -//namespace umbraco.presentation.dialogs -//{ -// /// -// /// Summary description for rollBack. -// /// -// public partial class rollBack : UmbracoEnsuredPage -// { -// public rollBack() -// { -// CurrentApp = Constants.Applications.Content.ToString(); - -// } -// private Document currentDoc = new Document(int.Parse(helper.Request("nodeId"))); - -// protected void version_load(object sender, EventArgs e) { - -// if (allVersions.SelectedValue != "") -// { -// diffPanel.Visible = true; -// Document rollback = new Document(currentDoc.Id, new Guid(allVersions.SelectedValue)); - -// propertiesCompare.Text = "" + Services.TextService.Localize("general/name") + ":" + rollback.Text + ""; -// propertiesCompare.Text += "" + Services.TextService.Localize("content/createDate") + ":" + rollback.VersionDate.ToLongDateString() + " " + rollback.VersionDate.ToLongTimeString() + " " + Services.TextService.Localize("general/by") + ": " + rollback.User.Name + ""; - -// if (rbl_mode.SelectedValue == "diff") -// lt_notice.Text = Services.TextService.Localize("rollback/diffHelp"); -// else -// lt_notice.Text = Services.TextService.Localize("rollback/htmlHelp"); - - -// var props = rollback.GenericProperties; -// foreach (Property p in props) -// { -// try -// { - -// if (p.Value != null) -// { - -// //new property value... -// string thevalue = p.Value.ToString(); - -// if (rbl_mode.SelectedValue == "diff") -// { - -// //if display mode is set to diff... -// thevalue = library.StripHtml(p.Value.ToString()); -// Property cP = currentDoc.getProperty(p.PropertyType); -// if (cP != null && cP.Value != null) -// { - -// string cThevalue = library.StripHtml(cP.Value.ToString()); - -// propertiesCompare.Text += "" + p.PropertyType.Name + ":" + library.ReplaceLineBreaks(cms.businesslogic.utilities.Diff.Diff2Html(cThevalue, thevalue)) + ""; - - -// } -// else -// { -// //If no current version of the value... display with no diff. -// propertiesCompare.Text += "" + p.PropertyType.Name + ":" + thevalue + ""; -// } - - -// } -// else -// { -// //If display mode is html -// propertiesCompare.Text += "" + p.PropertyType.Name + ":" + thevalue + ""; -// } - -// //previewVersionContent.Controls.Add(new LiteralControl("

" + p.PropertyType.Name + "
")); -// //previewVersionContent.Controls.Add(new LiteralControl(thevalue)); - -// } -// //previewVersionContent.Controls.Add(new LiteralControl("

")); -// } -// catch { } -// } - -// Button1.Visible = true; - - -// } -// else -// { -// diffPanel.Visible = false; -// Button1.Visible = false; -// } - -// } - -// protected void Page_Load(object sender, System.EventArgs e) -// { - -// if (String.IsNullOrEmpty(allVersions.SelectedValue)) -// rbl_mode.AutoPostBack = false; -// else -// rbl_mode.AutoPostBack = true; - -// currentVersionTitle.Text = currentDoc.Text; -// currentVersionMeta.Text = Services.TextService.Localize("content/createDate") + ": " + currentDoc.VersionDate.ToShortDateString() + " " + currentDoc.VersionDate.ToShortTimeString(); - -// if (!IsPostBack) { -// allVersions.Items.Add(new ListItem(Services.TextService.Localize("rollback/selectVersion")+ "...", "")); - -// foreach (DocumentVersionList dl in currentDoc.GetVersions()) -// { -// //we don't need to show the current version -// if (dl.Version == currentDoc.Version) -// continue; -// -// allVersions.Items.Add(new ListItem(dl.Text + " (" + Services.TextService.Localize("content/createDate") + ": " + dl.Date.ToShortDateString() + " " + dl.Date.ToShortTimeString() + ")", dl.Version.ToString())); -// } -// Button1.Text = Services.TextService.Localize("actions/rollback"); -// } -// } -// protected void doRollback_Click(object sender, System.EventArgs e) -// { -// if (allVersions.SelectedValue.Trim() != "") -// { -// Document d = new Document(int.Parse(helper.Request("nodeId"))); -// d.RollBack(new Guid(allVersions.SelectedValue), Security.CurrentUser); - -// BusinessLogic.Log.Add(BusinessLogic.LogTypes.RollBack, Security.CurrentUser, d.Id, "Version rolled back to revision '" + allVersions.SelectedValue + "'"); - -// Document rollback = new Document(d.Id, new Guid(allVersions.SelectedValue)); -// feedBackMsg.type = global::Umbraco.Web._Legacy.Controls.Feedback.feedbacktype.success; -// string[] vars = {rollback.Text, rollback.VersionDate.ToLongDateString()}; - -// feedBackMsg.Text = ui.Text("rollback", "documentRolledBack", vars, new global::umbraco.BusinessLogic.User(0)) + "

" + Services.TextService.Localize("closeThisWindow") + ""; -// diffPanel.Visible = false; -// pl_buttons.Visible = false; -// -// ClientTools.ReloadLocationIfMatched(string.Format("/content/content/edit/{0}", d.Id)); -// } -// } -// } -//} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.designer.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.designer.cs deleted file mode 100644 index ab313afa40..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.designer.cs +++ /dev/null @@ -1,150 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace umbraco.presentation.dialogs { - - - public partial class rollBack { - - ///

- /// JsInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; - - /// - /// feedBackMsg control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.Feedback feedBackMsg; - - /// - /// pp_selectVersion control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.Pane pp_selectVersion; - - /// - /// pp_currentVersion control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.PropertyPanel pp_currentVersion; - - /// - /// currentVersionTitle control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal currentVersionTitle; - - /// - /// currentVersionMeta control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal currentVersionMeta; - - /// - /// pp_rollBackTo control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.PropertyPanel pp_rollBackTo; - - /// - /// allVersions control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.DropDownList allVersions; - - /// - /// pp_view control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.PropertyPanel pp_view; - - /// - /// rbl_mode control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.RadioButtonList rbl_mode; - - /// - /// diffPanel control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel diffPanel; - - /// - /// lt_notice control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal lt_notice; - - /// - /// propertiesCompare control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal propertiesCompare; - - /// - /// pl_buttons control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlGenericControl pl_buttons; - - /// - /// Button1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Button Button1; - } -} From 6850599ce99aa4b68de4e5a43790b01b1318d51f Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 18 Oct 2018 15:04:40 +0100 Subject: [PATCH 31/52] Remove the emtpy folders from CSProj in the legacy umbraco.presentation folder --- src/Umbraco.Web/Umbraco.Web.csproj | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index d87ae5dd1c..63e497a1c4 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1449,10 +1449,7 @@ umbraco_org_umbraco_update_CheckForUpgrade
- - - - +