From 27f9490837e3a457cb763adc06054f65bb6772d0 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Dec 2018 10:14:18 +0100 Subject: [PATCH 01/12] fix docs build --- .../src/common/resources/relationtype.resource.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/relationtype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/relationtype.resource.js index f17aae0a6b..7f13a46d2f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/relationtype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/relationtype.resource.js @@ -35,7 +35,7 @@ function relationTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { /** * @ngdoc method * @name umbraco.resources.relationTypeResource#getRelationObjectTypes - * @methodof umbraco.resources.relationTypeResource + * @methodOf umbraco.resources.relationTypeResource * * @description * Gets a list of Umbraco object types which can be associated with a relation. @@ -54,7 +54,7 @@ function relationTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { /** * @ngdoc method * @name umbraco.resources.relationTypeResource#save - * @methodof umbraco.resources.relationTypeResource + * @methodOf umbraco.resources.relationTypeResource * * @description * Updates a relation type. @@ -74,7 +74,7 @@ function relationTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { /** * @ngdoc method * @name umbraco.resources.relationTypeResource#create - * @methodof umbraco.resources.relationTypeResource + * @methodOf umbraco.resources.relationTypeResource * * @description * Creates a new relation type. @@ -94,7 +94,7 @@ function relationTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { /** * @ngdoc method * @name umbraco.resources.relationTypeResource#deleteById - * @methodof umbraco.resources.relationTypeResource + * @methodOf umbraco.resources.relationTypeResource * * @description * Deletes a relation type with a given ID. From 0ae9d30373a06fbe030c41493cc00b90d3f48bfd Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 11 Dec 2018 09:43:47 +0000 Subject: [PATCH 02/12] Revert recent change to Forms dashboard back into XML config - now that we have a way to modify from Umbraco Forms component --- .../App_Plugins/UmbracoForms/package.manifest | 10 ---------- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 1 - src/Umbraco.Web.UI/config/Dashboard.config | 11 +++++++++++ 3 files changed, 11 insertions(+), 11 deletions(-) delete mode 100644 src/Umbraco.Web.UI/App_Plugins/UmbracoForms/package.manifest diff --git a/src/Umbraco.Web.UI/App_Plugins/UmbracoForms/package.manifest b/src/Umbraco.Web.UI/App_Plugins/UmbracoForms/package.manifest deleted file mode 100644 index c7ed4a957a..0000000000 --- a/src/Umbraco.Web.UI/App_Plugins/UmbracoForms/package.manifest +++ /dev/null @@ -1,10 +0,0 @@ -{ - "dashboards": [ - { - "name": "Install Umbraco Forms", - "alias": "installUmbracoForms", - "view": "views/dashboard/forms/formsdashboardintro.html", - "sections": [ "forms" ] - } - ] -} diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 130015ad53..5751e9155c 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -231,7 +231,6 @@ - 404handlers.config diff --git a/src/Umbraco.Web.UI/config/Dashboard.config b/src/Umbraco.Web.UI/config/Dashboard.config index 785fb61681..fec6ab34ae 100644 --- a/src/Umbraco.Web.UI/config/Dashboard.config +++ b/src/Umbraco.Web.UI/config/Dashboard.config @@ -22,6 +22,17 @@ +
+ + forms + + + + views/dashboard/forms/formsdashboardintro.html + + +
+
media From d06ccebf7c7d7c9c2987dbb2d86e97e877ee059a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Dec 2018 13:03:18 +0100 Subject: [PATCH 03/12] update docs for infinite editing --- .../overlays/umboverlay.directive.js | 216 ------------------ .../src/common/services/editor.service.js | 159 ++++++++++++- 2 files changed, 155 insertions(+), 220 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js index 9f9f1aa21e..99b89bf8cf 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js @@ -124,58 +124,6 @@ - -

Content Picker

-Opens a content picker.
-view: contentpicker - - - - - - - - - - - - - -
ParamTypeDetails
model.multiPickerBooleanPick one or multiple items
- - - - - - - - - - - - - -
ReturnsTypeDetails
model.selectionArrayArray of content objects
- - -

Icon Picker

-Opens an icon picker.
-view: iconpicker - - - - - - - - - - - - - -
ReturnsTypeDetails
model.iconStringThe icon class
-

Item Picker

Opens an item picker.
view: itempicker @@ -220,170 +168,6 @@ Opens an item picker.
-

Macro Picker

-Opens a media picker.
-view: macropicker - - - - - - - - - - - - - - - -
ParamTypeDetails
model.dialogDataObjectObject which contains array of allowedMacros. Set to null to allow all.
- - - - - - - - - - - - - - - - - - - - -
ReturnsTypeDetails
model.macroParamsArrayArray of macro params
model.selectedMacroObjectThe selected macro
- -

Media Picker

-Opens a media picker.
-view: mediapicker - - - - - - - - - - - - - - - - - - - - - - - - - -
ParamTypeDetails
model.multiPickerBooleanPick one or multiple items
model.onlyImagesBooleanOnly display files that have an image file-extension
model.disableFolderSelectBooleanDisable folder selection
- - - - - - - - - - - - - - - -
ReturnsTypeDetails
model.selectedImagesArrayArray of selected images
- -

Member Group Picker

-Opens a member group picker.
-view: membergrouppicker - - - - - - - - - - - - - - - -
ParamTypeDetails
model.multiPickerBooleanPick one or multiple items
- - - - - - - - - - - - - - - - - - - - -
ReturnsTypeDetails
model.selectedMemberGroupStringThe selected member group
model.selectedMemberGroups (multiPicker)ArrayThe selected member groups
- -

Member Picker

-Opens a member picker.
-view: memberpicker - - - - - - - - - - - - - - - -
ParamTypeDetails
model.multiPickerBooleanPick one or multiple items
- - - - - - - - - - - - - - -
ReturnsTypeDetails
model.selectionArrayArray of selected members/td> -
-

YSOD

Opens an overlay to show a custom YSOD.
view: ysod 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 650a210784..0dbd27b7a5 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 @@ -4,6 +4,76 @@ * * @description * Added in Umbraco 8.0. Application-wide service for handling infinite editing. + * + * +

Markup example

+
+    
+ + + +
+
+ +

Controller example

+
+    (function () {
+
+        "use strict";
+
+        function Controller() {
+
+            var vm = this;
+
+            vm.open = open;
+
+            function open() {
+                var mediaPickerOptions = {
+                    multiPicker: true,
+                    submit: function(model) {
+                        editorService.close();
+                    },
+                    close: function() {
+                        editorService.close();
+                    }
+                }
+                editorService.mediaPicker(mediaPickerOptions);
+            };
+        }
+
+        angular.module("umbraco").controller("My.Controller", Controller);
+    })();
+
+ +

Custom view example

+
+    (function () {
+
+        "use strict";
+
+        function Controller() {
+
+            var vm = this;
+
+            vm.open = open;
+
+            function open() {
+                var options = {
+                    view: "path/to/view.html"
+                    submit: function(model) {
+                        editorService.close();
+                    },
+                    close: function() {
+                        editorService.close();
+                    }
+                }
+                editorService.open(options);
+            };
+        }
+
+        angular.module("umbraco").controller("My.Controller", Controller);
+    })();
+
*/ (function () { "use strict"; @@ -43,6 +113,10 @@ * * @description * Method to open a new editor in infinite editing + * + * @param {Object} editor rendering options + * @param {String} editor.view Path to view + * @param {String} editor.size Sets the size of the editor ("Small"). If nothing is set it will use full width. */ function open(editor) { @@ -108,8 +182,12 @@ * * @description * Opens a media editor in infinite editing, the submit callback returns the updated content item + * @param {Object} editor rendering options * @param {String} editor.id The id of the content item * @param {Boolean} editor.create Create new content item + * @param {Function} editor.submit Callback function when the publish and close button is clicked. Returns the editor model object + * @param {Function} editor.close Callback function when the close button is clicked. + * * @returns {Object} editor object */ function contentEditor(editor) { @@ -124,6 +202,12 @@ * * @description * Opens a content picker in infinite editing, the submit callback returns an array of selected items + * + * @param {Object} editor rendering options + * @param {Boolean} editor.multiPicker Pick one or multiple items + * @param {Function} editor.submit Callback function when the submit button is clicked. Returns the editor model object + * @param {Function} editor.close Callback function when the close button is clicked. + * * @returns {Object} editor object */ function contentPicker(editor) { @@ -218,11 +302,13 @@ * * @description * Opens an embed editor in infinite editing. + * @param {Object} editor rendering options + * @param {String} editor.icon The icon class + * @param {String} editor.color The color class * @param {Callback} editor.submit Saves, submits, and closes the editor * @param {Callback} editor.close Closes the editor * @returns {Object} editor object */ - function linkPicker(editor) { editor.view = "views/common/infiniteeditors/linkpicker/linkpicker.html"; editor.size = "small"; @@ -236,6 +322,7 @@ * * @description * Opens a media editor in infinite editing, the submit callback returns the updated media item + * @param {Object} editor rendering options * @param {String} editor.id The id of the media item * @param {Boolean} editor.create Create new media item * @param {Callback} editor.submit Saves, submits, and closes the editor @@ -254,6 +341,7 @@ * * @description * Opens a media picker in infinite editing, the submit callback returns an array of selected media items + * @param {Object} editor rendering options * @param {Boolean} editor.multiPicker Pick one or multiple items * @param {Boolean} editor.onlyImages Only display files that have an image file-extension * @param {Boolean} editor.disableFolderSelect Disable folder selection @@ -276,6 +364,7 @@ * * @description * Opens an icon picker in infinite editing, the submit callback returns the selected icon + * @param {Object} editor rendering options * @param {Callback} editor.submit Submits the editor * @param {Callback} editor.close Closes the editor * @returns {Object} editor object @@ -293,6 +382,7 @@ * * @description * Opens the document type editor in infinite editing, the submit callback returns the saved document type + * @param {Object} editor rendering options * @param {Callback} editor.submit Submits the editor * @param {Callback} editor.close Closes the editor * @returns {Object} editor object @@ -309,6 +399,7 @@ * * @description * Opens the media type editor in infinite editing, the submit callback returns the saved media type + * @param {Object} editor rendering options * @param {Callback} editor.submit Submits the editor * @param {Callback} editor.close Closes the editor * @returns {Object} editor object @@ -318,24 +409,75 @@ open(editor); } + /** + * @ngdoc method + * @name umbraco.services.editorService#queryBuilder + * @methodOf umbraco.services.editorService + * + * @description + * Opens the query builder in infinite editing, the submit callback returns the generted query + * @param {Object} editor rendering options + * @param {Callback} editor.submit Submits the editor + * @param {Callback} editor.close Closes the editor + * @returns {Object} editor object + */ function queryBuilder(editor) { editor.view = "views/common/infiniteeditors/querybuilder/querybuilder.html"; editor.size = "small"; open(editor); } + /** + * @ngdoc method + * @name umbraco.services.editorService#treePicker + * @methodOf umbraco.services.editorService + * + * @description + * Opens the query builder in infinite editing, the submit callback returns the generted query + * @param {Object} editor rendering options + * @param {String} options.section tree section to display + * @param {String} options.treeAlias specific tree to display + * @param {Boolean} options.multiPicker should the tree pick one or multiple items before returning + * @param {Callback} editor.submit Submits the editor + * @param {Callback} editor.close Closes the editor + * @returns {Object} editor object + */ function treePicker(editor) { editor.view = "views/common/infiniteeditors/treepicker/treepicker.html"; editor.size = "small"; open(editor); } + /** + * @ngdoc method + * @name umbraco.services.editorService#nodePermissions + * @methodOf umbraco.services.editorService + * + * @description + * Opens the an editor to set node permissions. + * @param {Object} editor rendering options + * @param {Callback} editor.submit Submits the editor + * @param {Callback} editor.close Closes the editor + * @returns {Object} editor object + */ function nodePermissions(editor) { editor.view = "views/common/infiniteeditors/nodepermissions/nodepermissions.html"; editor.size = "small"; open(editor); } + /** + * @ngdoc method + * @name umbraco.services.editorService#insertCodeSnippet + * @methodOf umbraco.services.editorService + * + * @description + * Open an editor to insert code snippets into the code editor + * @param {Object} editor rendering options + * @param {Callback} editor.submit Submits the editor + * @param {Callback} editor.close Closes the editor + * @returns {Object} editor object + */ function insertCodeSnippet(editor) { editor.view = "views/common/infiniteeditors/insertcodesnippet/insertcodesnippet.html"; editor.size = "small"; @@ -349,6 +491,7 @@ * * @description * Opens the user group picker in infinite editing, the submit callback returns an array of the selected user groups + * @param {Object} editor rendering options * @param {Callback} editor.submit Submits the editor * @param {Callback} editor.close Closes the editor * @returns {Object} editor object @@ -366,6 +509,7 @@ * * @description * Opens the user group picker in infinite editing, the submit callback returns the saved template + * @param {Object} editor rendering options * @param {String} editor.id The template id * @param {Callback} editor.submit Submits the editor * @param {Callback} editor.close Closes the editor @@ -382,7 +526,8 @@ * @methodOf umbraco.services.editorService * * @description - * Opens the section picker in infinite editing, the submit callback returns an array of the selected sections + * Opens the section picker in infinite editing, the submit callback returns an array of the selected sections¨ + * @param {Object} editor rendering options * @param {Callback} editor.submit Submits the editor * @param {Callback} editor.close Closes the editor * @returns {Object} editor object @@ -400,6 +545,7 @@ * * @description * Opens the insert field editor in infinite editing, the submit callback returns the code snippet + * @param {Object} editor rendering options * @param {Callback} editor.submit Submits the editor * @param {Callback} editor.close Closes the editor * @returns {Object} editor object @@ -417,6 +563,7 @@ * * @description * Opens the template sections editor in infinite editing, the submit callback returns the type to insert + * @param {Object} editor rendering options * @param {Callback} editor.submit Submits the editor * @param {Callback} editor.close Closes the editor * @returns {Object} editor object @@ -429,11 +576,12 @@ /** * @ngdoc method - * @name umbraco.services.editorService#sectionPicker + * @name umbraco.services.editorService#userPicker * @methodOf umbraco.services.editorService * * @description * Opens the section picker in infinite editing, the submit callback returns an array of the selected users + * @param {Object} editor rendering options * @param {Callback} editor.submit Submits the editor * @param {Callback} editor.close Closes the editor * @returns {Object} editor object @@ -452,6 +600,7 @@ * @description * Opens the section picker in infinite editing, the submit callback returns an array of the selected items * + * @param {Object} editor rendering options * @param {Array} editor.availableItems Array of available items. * @param {Array} editor.selectedItems Array of selected items. When passed in the selected items will be filtered from the available items. * @param {Boolean} editor.filter Set to false to hide the filter. @@ -485,12 +634,14 @@ /** * @ngdoc method - * @name umbraco.services.editorService#macroPicker + * @name umbraco.services.editorService#memberGroupPicker * @methodOf umbraco.services.editorService * * @description * Opens a member group picker in infinite editing. * + * @param {Object} editor rendering options + * @param {Object} editor.multiPicker Pick one or multiple items. * @param {Callback} editor.submit Submits the editor. * @param {Callback} editor.close Closes the editor. * @returns {Object} editor object From b19f9c81140991549118b7b7b5ee071c423e222f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Dec 2018 13:39:12 +0100 Subject: [PATCH 04/12] update styling on forms install dashboard --- src/Umbraco.Web.UI.Client/src/less/dashboards.less | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/dashboards.less b/src/Umbraco.Web.UI.Client/src/less/dashboards.less index 5fd0e25be1..cc13ad31fd 100644 --- a/src/Umbraco.Web.UI.Client/src/less/dashboards.less +++ b/src/Umbraco.Web.UI.Client/src/less/dashboards.less @@ -1,13 +1,14 @@ .umb-dashboards-forms-install { background: url('../img/forms/installer-background.png'); background-repeat: repeat-x; - position: relative; - top: -30px; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; padding-top: 30px; - box-shadow: inset 0px -40px 30px 25px rgba(255,255,255,1); - -moz-border-radius: 0px 0px 200px 200px; - -webkit-border-radius: 0px 0px 200px 200px; - border-radius: 0px 0px 200px 200px; + background-color: @white; + overflow: auto; small { font-size: 14px; From 0dff7680fd695088984cb93c8affcc20c7bdeffe Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 11 Dec 2018 14:02:54 +0100 Subject: [PATCH 05/12] Fix ContentTypeServiceTests (but, why???) --- .../Services/ContentTypeServiceTests.cs | 71 +++++++++++-------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs index bc0854bdb7..8ea4856861 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs @@ -148,7 +148,7 @@ namespace Umbraco.Tests.Services //change the content type to be invariant, we will also update the name here to detect the copy changes doc.SetCultureName("Hello2", "en-US"); ServiceContext.ContentService.Save(doc); - contentType.Variations = ContentVariation.Nothing; + contentType.Variations = ContentVariation.Nothing; ServiceContext.ContentTypeService.Save(contentType); doc = ServiceContext.ContentService.GetById(doc.Id); //re-get @@ -372,7 +372,7 @@ namespace Umbraco.Tests.Services doc2 = ServiceContext.ContentService.GetById(doc2.Id); //re-get //this will be null because the doc type was changed back to variant but it's property types don't get changed back - Assert.IsNull(doc.GetValue("title", "en-US")); + Assert.IsNull(doc.GetValue("title", "en-US")); Assert.IsNull(doc2.GetValue("title", "en-US")); } @@ -1714,50 +1714,65 @@ namespace Umbraco.Tests.Services // Arrange var service = ServiceContext.ContentTypeService; + // create 'page' content type with a 'Content_' group var page = MockedContentTypes.CreateSimpleContentType("page", "Page", null, false, "Content_"); + Assert.IsTrue(page.PropertyGroups.Contains("Content_")); + Assert.AreEqual(3, page.PropertyTypes.Count()); service.Save(page); + + // create 'contentPage' content type as a child of 'page' var contentPage = MockedContentTypes.CreateSimpleContentType("contentPage", "Content Page", page, true); - service.Save(contentPage); - var composition = MockedContentTypes.CreateMetaContentType(); - composition.AddPropertyGroup("Content"); - service.Save(composition); - //Adding Meta-composition to child doc type - contentPage.AddContentType(composition); + Assert.AreEqual(3, contentPage.PropertyTypes.Count()); service.Save(contentPage); - // Act - var propertyTypeOne = new PropertyType(Constants.PropertyEditors.Aliases.TextBox, ValueStorageType.Ntext, "testTextbox") + // add 'Content' group to 'meta' content type + var meta = MockedContentTypes.CreateMetaContentType(); + meta.AddPropertyGroup("Content"); + Assert.AreEqual(2, meta.PropertyTypes.Count()); + service.Save(meta); + + // add 'meta' content type to 'contentPage' composition + contentPage.AddContentType(meta); + service.Save(contentPage); + + // add property 'prop1' to 'contentPage' group 'Content_' + var prop1 = new PropertyType(Constants.PropertyEditors.Aliases.TextBox, ValueStorageType.Ntext, "testTextbox") { Name = "Test Textbox", Description = "", Mandatory = false, SortOrder = 1, DataTypeId = -88 }; - var firstOneAdded = contentPage.AddPropertyType(propertyTypeOne, "Content_"); - var propertyTypeTwo = new PropertyType(Constants.PropertyEditors.Aliases.TextBox, ValueStorageType.Ntext, "anotherTextbox") + var prop1Added = contentPage.AddPropertyType(prop1, "Content_"); + Assert.IsTrue(prop1Added); + + // add property 'prop2' to 'contentPage' group 'Content' + var prop2 = new PropertyType(Constants.PropertyEditors.Aliases.TextBox, ValueStorageType.Ntext, "anotherTextbox") { Name = "Another Test Textbox", Description = "", Mandatory = false, SortOrder = 1, DataTypeId = -88 }; - var secondOneAdded = contentPage.AddPropertyType(propertyTypeTwo, "Content"); + var prop2Added = contentPage.AddPropertyType(prop2, "Content"); + Assert.IsTrue(prop2Added); + + // save 'contentPage' content type service.Save(contentPage); - Assert.That(page.PropertyGroups.Contains("Content_"), Is.True); - var propertyGroup = page.PropertyGroups["Content_"]; - page.PropertyGroups.Add(new PropertyGroup(true) { Id = propertyGroup.Id, Name = "ContentTab", SortOrder = 0}); + var group = page.PropertyGroups["Content_"]; + group.Name = "ContentTab"; // rename the group service.Save(page); + Assert.AreEqual(3, page.PropertyTypes.Count()); - // Assert - Assert.That(firstOneAdded, Is.True); - Assert.That(secondOneAdded, Is.True); + // get 'contentPage' content type again + var contentPageAgain = service.Get("contentPage"); + Assert.IsNotNull(contentPageAgain); - var contentType = service.Get("contentPage"); - Assert.That(contentType, Is.Not.Null); + // assert that 'Content_' group is still there because we don't propagate renames + var findGroup = contentPageAgain.CompositionPropertyGroups.FirstOrDefault(x => x.Name == "Content_"); + Assert.IsNotNull(findGroup); - var compositionPropertyGroups = contentType.CompositionPropertyGroups; - - // now it is still 1, because we don't propagate renames anymore - Assert.That(compositionPropertyGroups.Count(x => x.Name.Equals("Content_")), Is.EqualTo(1)); - - var propertyTypeCount = contentType.PropertyTypes.Count(); - var compPropertyTypeCount = contentType.CompositionPropertyTypes.Count(); + // count all property types (local and composed) + var propertyTypeCount = contentPageAgain.PropertyTypes.Count(); Assert.That(propertyTypeCount, Is.EqualTo(5)); + + // count composed property types + var compPropertyTypeCount = contentPageAgain.CompositionPropertyTypes.Count(); Assert.That(compPropertyTypeCount, Is.EqualTo(10)); } From b0157d7116603c6ab6211ce329c4c70021309e1c Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 11 Dec 2018 14:08:44 +0000 Subject: [PATCH 06/12] We do not need to ship with these Umbraco Forms trees in the config file --- src/Umbraco.Web.UI/config/trees.config | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI/config/trees.config b/src/Umbraco.Web.UI/config/trees.config index 2b99f8751f..7f7aeca8a7 100644 --- a/src/Umbraco.Web.UI/config/trees.config +++ b/src/Umbraco.Web.UI/config/trees.config @@ -30,9 +30,5 @@ - - - - - + From 767cd93f08b83acc175aa2311ff29936260147ee Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Tue, 11 Dec 2018 14:09:44 +0000 Subject: [PATCH 07/12] Adds in some logic if we have no child trees for that application/section then we create a SingleTreeRoot --- .../Trees/ApplicationTreeController.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web/Trees/ApplicationTreeController.cs b/src/Umbraco.Web/Trees/ApplicationTreeController.cs index c1192b6909..d824f32f4b 100644 --- a/src/Umbraco.Web/Trees/ApplicationTreeController.cs +++ b/src/Umbraco.Web/Trees/ApplicationTreeController.cs @@ -78,10 +78,20 @@ namespace Umbraco.Web.Trees } } - var multiTree = TreeRootNode.CreateMultiTreeRoot(collection); - multiTree.Name = Services.TextService.Localize("sections/" + application); + if(collection.Count > 0) + { + var multiTree = TreeRootNode.CreateMultiTreeRoot(collection); + multiTree.Name = Services.TextService.Localize("sections/" + application); - return multiTree; + return multiTree; + } + + //Otherwise its a application/section with no trees (aka a full screen app) + //For example we do not have a Forms tree definied in C# & can not attribute with [Tree(isSingleNodeTree:true0] + var rootId = Constants.System.Root.ToString(CultureInfo.InvariantCulture); + var section = Services.TextService.Localize("sections/" + application); + + return TreeRootNode.CreateSingleTreeRoot(rootId, null, null, section, TreeNodeCollection.Empty, true); } var rootNodeGroups = new List(); From e1743ae3ea2d8331b8f136d222c92f53c6d95f3f Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 12 Dec 2018 12:05:19 +1100 Subject: [PATCH 08/12] Changes IValueSetBuilder to not be strongly typed, no need for that --- src/Umbraco.Examine/IValueSetBuilder.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Examine/IValueSetBuilder.cs b/src/Umbraco.Examine/IValueSetBuilder.cs index 89aa907926..1c4890f404 100644 --- a/src/Umbraco.Examine/IValueSetBuilder.cs +++ b/src/Umbraco.Examine/IValueSetBuilder.cs @@ -5,18 +5,17 @@ using Umbraco.Core.Models; namespace Umbraco.Examine { /// - /// Creates a collection of to be indexed based on a collection of + /// Creates a collection of to be indexed based on a collection of /// - /// - public interface IValueSetBuilder - where TContent : IContentBase + /// + public interface IValueSetBuilder { /// - /// Creates a collection of to be indexed based on a collection of + /// Creates a collection of to be indexed based on a collection of /// /// /// - IEnumerable GetValueSets(params TContent[] content); + IEnumerable GetValueSets(params T[] content); } } From 15c7d7ce77b7c9c3e81340ec926b7fbc9da718c1 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 12 Dec 2018 12:37:21 +1100 Subject: [PATCH 09/12] Creates a sub-generic interface for creating indexes --- src/Umbraco.Examine/IIndexCreator.cs | 13 +++++++++++++ src/Umbraco.Examine/IIndexDiagnostics.cs | 3 --- src/Umbraco.Examine/Umbraco.Examine.csproj | 1 + src/Umbraco.Web/Search/IUmbracoIndexesCreator.cs | 5 +++-- 4 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 src/Umbraco.Examine/IIndexCreator.cs diff --git a/src/Umbraco.Examine/IIndexCreator.cs b/src/Umbraco.Examine/IIndexCreator.cs new file mode 100644 index 0000000000..3b8f683990 --- /dev/null +++ b/src/Umbraco.Examine/IIndexCreator.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using Examine; + +namespace Umbraco.Examine +{ + /// + /// Creates 's + /// + public interface IIndexCreator + { + IEnumerable Create(); + } +} diff --git a/src/Umbraco.Examine/IIndexDiagnostics.cs b/src/Umbraco.Examine/IIndexDiagnostics.cs index 04ca4a6ab9..29d530c2d0 100644 --- a/src/Umbraco.Examine/IIndexDiagnostics.cs +++ b/src/Umbraco.Examine/IIndexDiagnostics.cs @@ -1,12 +1,9 @@ using System; using System.Collections.Generic; -using Examine; using Umbraco.Core; namespace Umbraco.Examine { - - /// /// Exposes diagnostic information about an index /// diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj index 0aedf6e754..aa57707b2e 100644 --- a/src/Umbraco.Examine/Umbraco.Examine.csproj +++ b/src/Umbraco.Examine/Umbraco.Examine.csproj @@ -66,6 +66,7 @@ + diff --git a/src/Umbraco.Web/Search/IUmbracoIndexesCreator.cs b/src/Umbraco.Web/Search/IUmbracoIndexesCreator.cs index 58014597d2..d654e4effd 100644 --- a/src/Umbraco.Web/Search/IUmbracoIndexesCreator.cs +++ b/src/Umbraco.Web/Search/IUmbracoIndexesCreator.cs @@ -1,13 +1,14 @@ using System.Collections.Generic; using Examine; +using Umbraco.Examine; namespace Umbraco.Web.Search { + /// /// /// Used to create the Umbraco indexes /// - public interface IUmbracoIndexesCreator + public interface IUmbracoIndexesCreator : IIndexCreator { - IEnumerable Create(); } } From 7cb83373cae5c9961c7d88de8da5afc1fc385881 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 12 Dec 2018 12:46:58 +1100 Subject: [PATCH 10/12] Creates base class LuceneIndexCreator --- src/Umbraco.Examine/LuceneIndexCreator.cs | 39 +++++++++++++++++++ src/Umbraco.Examine/Umbraco.Examine.csproj | 1 + .../Search/UmbracoIndexesCreator.cs | 26 +++---------- 3 files changed, 46 insertions(+), 20 deletions(-) create mode 100644 src/Umbraco.Examine/LuceneIndexCreator.cs diff --git a/src/Umbraco.Examine/LuceneIndexCreator.cs b/src/Umbraco.Examine/LuceneIndexCreator.cs new file mode 100644 index 0000000000..c1fe7ae772 --- /dev/null +++ b/src/Umbraco.Examine/LuceneIndexCreator.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using System.IO; +using Examine; +using Lucene.Net.Store; +using Umbraco.Core.IO; + +namespace Umbraco.Examine +{ + /// + /// + /// Abstract class for creating Lucene based Indexes + /// + public abstract class LuceneIndexCreator : IIndexCreator + { + public abstract IEnumerable Create(); + + /// + /// Creates a file system based Lucene with the correct locking guidelines for Umbraco + /// + /// + /// + public virtual Lucene.Net.Store.Directory CreateFileSystemLuceneDirectory(string name) + { + //TODO: We should have a single AppSetting to be able to specify a default DirectoryFactory so we can have a single + //setting to configure all indexes that use this to easily swap the directory to Sync/%temp%/blog, etc... + + var dirInfo = new DirectoryInfo(Path.Combine(IOHelper.MapPath(SystemDirectories.Data), "TEMP", "ExamineIndexes", name)); + if (!dirInfo.Exists) + System.IO.Directory.CreateDirectory(dirInfo.FullName); + + var luceneDir = new SimpleFSDirectory(dirInfo); + //we want to tell examine to use a different fs lock instead of the default NativeFSFileLock which could cause problems if the appdomain + //terminates and in some rare cases would only allow unlocking of the file if IIS is forcefully terminated. Instead we'll rely on the simplefslock + //which simply checks the existence of the lock file + luceneDir.SetLockFactory(new NoPrefixSimpleFsLockFactory(dirInfo)); + return luceneDir; + } + } +} diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj index aa57707b2e..66b1f09068 100644 --- a/src/Umbraco.Examine/Umbraco.Examine.csproj +++ b/src/Umbraco.Examine/Umbraco.Examine.csproj @@ -89,6 +89,7 @@ + Properties\SolutionInfo.cs diff --git a/src/Umbraco.Web/Search/UmbracoIndexesCreator.cs b/src/Umbraco.Web/Search/UmbracoIndexesCreator.cs index f8b2c6ef8b..3723dedc48 100644 --- a/src/Umbraco.Web/Search/UmbracoIndexesCreator.cs +++ b/src/Umbraco.Web/Search/UmbracoIndexesCreator.cs @@ -21,7 +21,7 @@ namespace Umbraco.Web.Search /// /// Creates the indexes used by Umbraco /// - public class UmbracoIndexesCreator : IUmbracoIndexesCreator + public class UmbracoIndexesCreator : LuceneIndexCreator, IUmbracoIndexesCreator { //TODO: we should inject the different IValueSetValidator so devs can just register them instead of overriding this class? @@ -45,7 +45,7 @@ namespace Umbraco.Web.Search /// Creates the Umbraco indexes /// /// - public IEnumerable Create() + public override IEnumerable Create() { return new [] { @@ -61,7 +61,7 @@ namespace Umbraco.Web.Search Constants.UmbracoIndexes.InternalIndexName, //fixme - how to deal with languages like in UmbracoContentIndexer.CreateFieldValueTypes UmbracoExamineIndex.UmbracoIndexFieldDefinitions, - GetFileSystemLuceneDirectory(Constants.UmbracoIndexes.InternalIndexPath), + CreateFileSystemLuceneDirectory(Constants.UmbracoIndexes.InternalIndexPath), new CultureInvariantWhitespaceAnalyzer(), ProfilingLogger, LanguageService, @@ -75,7 +75,7 @@ namespace Umbraco.Web.Search Constants.UmbracoIndexes.ExternalIndexName, //fixme - how to deal with languages like in UmbracoContentIndexer.CreateFieldValueTypes UmbracoExamineIndex.UmbracoIndexFieldDefinitions, - GetFileSystemLuceneDirectory(Constants.UmbracoIndexes.ExternalIndexPath), + CreateFileSystemLuceneDirectory(Constants.UmbracoIndexes.ExternalIndexPath), new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30), ProfilingLogger, LanguageService, @@ -89,27 +89,13 @@ namespace Umbraco.Web.Search Constants.UmbracoIndexes.MembersIndexName, //fixme - how to deal with languages like in UmbracoContentIndexer.CreateFieldValueTypes UmbracoExamineIndex.UmbracoIndexFieldDefinitions, - GetFileSystemLuceneDirectory(Constants.UmbracoIndexes.MembersIndexPath), + CreateFileSystemLuceneDirectory(Constants.UmbracoIndexes.MembersIndexPath), new CultureInvariantWhitespaceAnalyzer(), ProfilingLogger, GetMemberValueSetValidator()); return index; } - - public virtual Lucene.Net.Store.Directory GetFileSystemLuceneDirectory(string name) - { - var dirInfo = new DirectoryInfo(Path.Combine(IOHelper.MapPath(SystemDirectories.Data), "TEMP", "ExamineIndexes", name)); - if (!dirInfo.Exists) - System.IO.Directory.CreateDirectory(dirInfo.FullName); - - var luceneDir = new SimpleFSDirectory(dirInfo); - //we want to tell examine to use a different fs lock instead of the default NativeFSFileLock which could cause problems if the appdomain - //terminates and in some rare cases would only allow unlocking of the file if IIS is forcefully terminated. Instead we'll rely on the simplefslock - //which simply checks the existence of the lock file - luceneDir.SetLockFactory(new NoPrefixSimpleFsLockFactory(dirInfo)); - return luceneDir; - } - + public virtual IContentValueSetValidator GetContentValueSetValidator() { return new ContentValueSetValidator(false, true, PublicAccessService); From b5da641d4823f96f3e8f18bbf8fcf54ad99e9548 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 12 Dec 2018 13:23:29 +1100 Subject: [PATCH 11/12] Uses the DefaultLockFactory to set the lock --- src/Umbraco.Examine/LuceneIndexCreator.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Examine/LuceneIndexCreator.cs b/src/Umbraco.Examine/LuceneIndexCreator.cs index c1fe7ae772..572de1e8a8 100644 --- a/src/Umbraco.Examine/LuceneIndexCreator.cs +++ b/src/Umbraco.Examine/LuceneIndexCreator.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.IO; using Examine; +using Examine.LuceneEngine.Directories; using Lucene.Net.Store; using Umbraco.Core.IO; @@ -29,10 +30,13 @@ namespace Umbraco.Examine System.IO.Directory.CreateDirectory(dirInfo.FullName); var luceneDir = new SimpleFSDirectory(dirInfo); + //we want to tell examine to use a different fs lock instead of the default NativeFSFileLock which could cause problems if the appdomain //terminates and in some rare cases would only allow unlocking of the file if IIS is forcefully terminated. Instead we'll rely on the simplefslock //which simply checks the existence of the lock file - luceneDir.SetLockFactory(new NoPrefixSimpleFsLockFactory(dirInfo)); + // The full syntax of this is: new NoPrefixSimpleFsLockFactory(dirInfo) + // however, we are setting the DefaultLockFactory in startup so we'll use that instead since it can be managed globally. + luceneDir.SetLockFactory(DirectoryFactory.DefaultLockFactory(dirInfo)); return luceneDir; } } From 85b25485da05f2fcc7e86b8e7b856f0756bfcd11 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 12 Dec 2018 13:34:54 +1100 Subject: [PATCH 12/12] removes trees from trees.Release.config --- src/Umbraco.Web.UI/config/trees.Release.config | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI/config/trees.Release.config b/src/Umbraco.Web.UI/config/trees.Release.config index 7b5a9e5e2a..bd75e97c38 100644 --- a/src/Umbraco.Web.UI/config/trees.Release.config +++ b/src/Umbraco.Web.UI/config/trees.Release.config @@ -30,9 +30,5 @@ - - - - - +