From 33810d56c771e8b2dbb80c79acc071f95ec581c2 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Thu, 23 Jul 2015 09:56:01 +0100 Subject: [PATCH 01/41] Made all alias comparisons case insensitive Changed tab selection UI to be dropdown auto populated by doctype selection to prevent mistakes --- .../Web/Controllers/NestedContentApiController.cs | 3 ++- .../NestedContent/Js/nestedcontent.controllers.js | 15 +++++++++++++-- .../NestedContent/Js/nestedcontent.directives.js | 2 +- .../Views/nestedcontent.doctypepicker.html | 10 ++++++---- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Web/Controllers/NestedContentApiController.cs b/src/Our.Umbraco.NestedContent/Web/Controllers/NestedContentApiController.cs index 4df5208..dc7f109 100644 --- a/src/Our.Umbraco.NestedContent/Web/Controllers/NestedContentApiController.cs +++ b/src/Our.Umbraco.NestedContent/Web/Controllers/NestedContentApiController.cs @@ -22,7 +22,8 @@ public IEnumerable GetContentTypes() guid = x.Key, name = x.Name, alias = x.Alias, - icon = x.Icon + icon = x.Icon, + tabs = x.CompositionPropertyGroups.Select(y => y.Name).Distinct() }); } } diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js index a00887f..71af40b 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js @@ -16,6 +16,17 @@ ); } + $scope.selectedDocTypeTabs = function(cfg) { + var dt = _.find($scope.model.docTypes, function(itm) { + return itm.alias.toLowerCase() == cfg.ncAlias.toLowerCase(); + }); + var tabs = dt ? dt.tabs : []; + if (!_.contains(tabs, cfg.ncTabAlias)) { + cfg.ncTabAlias = tabs[0]; + } + return tabs; + } + $scope.remove = function (index) { $scope.model.value.splice(index, 1); } @@ -227,8 +238,8 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest contentResource.getScaffold(-20, contentType.ncAlias).then(function(scaffold) { // remove all tabs except the specified tab var tab = _.find(scaffold.tabs, function(tab) { - return tab.id != 0 && (tab.alias == contentType.ncTabAlias || contentType.ncTabAlias == ""); - }) + return tab.id != 0 && (tab.alias.toLowerCase() == contentType.ncTabAlias.toLowerCase() || contentType.ncTabAlias == ""); + }); scaffold.tabs = []; if (tab) { scaffold.tabs.push(tab); diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js index 242f400..08dfce2 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js @@ -9,7 +9,7 @@ if ($scope.tabAlias) { angular.forEach($scope.ngModel.tabs, function (value, key) { - if (value.alias == $scope.tabAlias) { + if (value.alias.toLowerCase() == $scope.tabAlias.toLowerCase()) { tab = value; return; } diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html index e0b7e83..039e87b 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html @@ -21,12 +21,14 @@ - + - + From b2e38f3a495121af539434d460353ac91aeb8d66 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Thu, 23 Jul 2015 09:57:53 +0100 Subject: [PATCH 02/41] Updated doctype picker control headings --- .../NestedContent/Views/nestedcontent.doctypepicker.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html index 039e87b..4a828a6 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html @@ -5,13 +5,13 @@ - Document type + Document Type - Tab alias + Tab - Name template + Name Template From d6cbf421e69ae41eb336aa6904e362be53f9fc48 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Thu, 23 Jul 2015 09:58:43 +0100 Subject: [PATCH 03/41] Updated the doctype pickers help text --- .../NestedContent/Views/nestedcontent.doctypepicker.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html index 4a828a6..5a42748 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html @@ -48,7 +48,7 @@

Tab:
- Enter the alias of the tab who's properties should be displayed. If left blank, the first tab on the doc type will be used. + Select the tab who's properties should be displayed. If left blank, the first tab on the doc type will be used.

Name template:
From 56bf9f736372562ea40ffd72af44e6ad5c0b222e Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Thu, 23 Jul 2015 10:00:09 +0100 Subject: [PATCH 04/41] Updated screenshot with doctype picker updates --- docs/assets/img/screenshot-01.png | Bin 38149 -> 37583 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/assets/img/screenshot-01.png b/docs/assets/img/screenshot-01.png index 2d984c2139b9595abb3c784fe8e00e849291229e..d3d3f2b807b8508ed756c0e945ff90ce85e67a23 100644 GIT binary patch literal 37583 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
  • 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 OKuSVhJm>lAcmEr-IA*Q@ literal 38149 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 From 7a2fc3716bfb749d7b7534a3e10051d01ac7cab5 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Sat, 25 Jul 2015 10:55:46 +0100 Subject: [PATCH 05/41] Added extra classes to the nested content wrapper to distinguish between wide/narrow mode so that we only expand text fields etc when in narrow mode so that we maintain consistency of controls when in wide mode --- .../NestedContent/Css/nestedcontent.css | 10 +++++----- .../Js/nestedcontent.controllers.js | 2 +- .../NestedContent/Views/nestedcontent.html | 20 ++++++++++--------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css index 5469cad..885efda 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css @@ -167,18 +167,18 @@ margin-left: 10px; } -.form-horizontal .nested-content .control-label +.form-horizontal .nested-content--narrow .control-label { width: 30%; } -.form-horizontal .nested-content .controls-row +.form-horizontal .nested-content--narrow .controls-row { margin-left: 40% !important; } -.form-horizontal .nested-content .controls-row .umb-textstring, -.form-horizontal .nested-content .controls-row .umb-textarea +.form-horizontal .nested-content--narrow .controls-row .umb-textstring, +.form-horizontal .nested-content--narrow .controls-row .umb-textarea { width: 95%; -} +} \ No newline at end of file diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js index 71af40b..f2ac033 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js @@ -83,8 +83,8 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest $scope.maxItems = 1000; $scope.singleMode = $scope.minItems == 1 && $scope.maxItems == 1; - $scope.showIcons = $scope.model.config.showIcons || true; + $scope.wideMode = $scope.model.config.hideLabel == "1"; $scope.overlayMenu = { show: false, diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html index 9966bd4..5781bc9 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html @@ -1,16 +1,18 @@ -
    +
    - +
    +
    - +
    - +
    From c173fead83f32cd4e9e1f281d2b60dc45e6c4313 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Tue, 11 Aug 2015 13:58:16 +0100 Subject: [PATCH 06/41] Updated detached published content to inherit a number of properties from the containing node --- .../Converters/NestedContentValueConverter.cs | 5 +++++ .../Models/DetachedPublishedContent.cs | 17 ++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs index 0399707..2f83a20 100644 --- a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs +++ b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs @@ -85,10 +85,15 @@ public override object ConvertDataToSource(PublishedPropertyType propertyType, o // Do nothing, we just want to parse out the name if we can } + // Get the current request node we are embedded in + var pcr = UmbracoContext.Current.PublishedContentRequest; + var containerNode = pcr != null && pcr.HasPublishedContent ? pcr.PublishedContent : null; + processedValue.Add(new DetachedPublishedContent( nameObj == null ? null : nameObj.ToString(), publishedContentType, properties.ToArray(), + containerNode, i)); } diff --git a/src/Our.Umbraco.NestedContent/Models/DetachedPublishedContent.cs b/src/Our.Umbraco.NestedContent/Models/DetachedPublishedContent.cs index d8bd5a6..641563e 100644 --- a/src/Our.Umbraco.NestedContent/Models/DetachedPublishedContent.cs +++ b/src/Our.Umbraco.NestedContent/Models/DetachedPublishedContent.cs @@ -15,10 +15,12 @@ internal class DetachedPublishedContent : PublishedContentBase private readonly IEnumerable _properties; private readonly int _sortOrder; private readonly bool _isPreviewing; + private readonly IPublishedContent _containerNode; public DetachedPublishedContent(string name, PublishedContentType contentType, IEnumerable properties, + IPublishedContent containerNode = null, int sortOrder = 0, bool isPreviewing = false) { @@ -27,6 +29,7 @@ public DetachedPublishedContent(string name, _properties = properties; _sortOrder = sortOrder; _isPreviewing = isPreviewing; + _containerNode = containerNode; } public override int Id @@ -109,22 +112,22 @@ public override string UrlName public override string WriterName { - get { return null; } + get { return _containerNode != null ? _containerNode.WriterName : null; } } public override string CreatorName { - get { return null; } + get { return _containerNode != null ? _containerNode.CreatorName : null; } } public override int WriterId { - get { return 0; } + get { return _containerNode != null ? _containerNode.WriterId : 0; } } public override int CreatorId { - get { return 0; } + get { return _containerNode != null ? _containerNode.CreatorId : 0; } } public override string Path @@ -134,17 +137,17 @@ public override string Path public override DateTime CreateDate { - get { return DateTime.MinValue; } + get { return _containerNode != null ? _containerNode.CreateDate : DateTime.MinValue; } } public override DateTime UpdateDate { - get { return DateTime.MinValue; } + get { return _containerNode != null ? _containerNode.UpdateDate : DateTime.MinValue; } } public override Guid Version { - get { return Guid.Empty; } + get { return _containerNode != null ? _containerNode.Version : Guid.Empty; } } public override int Level From 77b8eb4475aea6518d7b3e15898965a4b969e022 Mon Sep 17 00:00:00 2001 From: Jeavon Leopold Date: Tue, 25 Aug 2015 19:43:13 +0100 Subject: [PATCH 07/41] Add install.ps1 that copies the "App_Plugins/NestedContent" folder to the project if it's been excluded from the project since original installation --- build/Install.ps1 | 18 ++++++++++++++++++ build/package.proj | 4 +++- src/Our.Umbraco.NestedContent.sln | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 build/Install.ps1 diff --git a/build/Install.ps1 b/build/Install.ps1 new file mode 100644 index 0000000..5e320c1 --- /dev/null +++ b/build/Install.ps1 @@ -0,0 +1,18 @@ +param($installPath, $toolsPath, $package, $project) + +$appPluginsFolder = $project.ProjectItems | Where-Object { $_.Name -eq "App_Plugins" } +$nestedContentFolder = $appPluginsFolder.ProjectItems | Where-Object { $_.Name -eq "NestedContent" } + +$newPackageFiles = "$installPath\Content\App_Plugins\NestedContent" + +$projFile = Get-Item ($project.FullName) +$projDirectory = $projFile.DirectoryName +$projectPath = Join-Path $projDirectory -ChildPath "App_Plugins" +$projectPathExists = Test-Path $projectPath + +if ($projectPathExists -and !$nestedContentFolder) { + Write-Host "Updating Nested Content App_Plugin files using PS as they have been excluded from the project" + Copy-Item $newPackageFiles $projectPath -Recurse -Force +} + + diff --git a/build/package.proj b/build/package.proj index 747d160..cd53a5d 100644 --- a/build/package.proj +++ b/build/package.proj @@ -123,6 +123,7 @@ + @@ -132,7 +133,8 @@ - + + diff --git a/src/Our.Umbraco.NestedContent.sln b/src/Our.Umbraco.NestedContent.sln index 9362de1..b00a091 100644 --- a/src/Our.Umbraco.NestedContent.sln +++ b/src/Our.Umbraco.NestedContent.sln @@ -16,6 +16,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Package", "Build Pack ..\appveyor.yml = ..\appveyor.yml ..\build-appveyor.cmd = ..\build-appveyor.cmd ..\build.cmd = ..\build.cmd + ..\build\install.ps1 = ..\build\install.ps1 ..\build\package.nuspec = ..\build\package.nuspec ..\build\package.proj = ..\build\package.proj ..\build\package.xml = ..\build\package.xml From 6ea4b22ebe176a0f9afaff747d824cc682f8f960 Mon Sep 17 00:00:00 2001 From: Jeavon Leopold Date: Wed, 26 Aug 2015 09:56:47 +0100 Subject: [PATCH 08/41] Fix so that Install.ps1 doesn't do anything for website projects --- build/Install.ps1 | 21 +++++++++++++-------- src/Our.Umbraco.NestedContent.sln | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/build/Install.ps1 b/build/Install.ps1 index 5e320c1..03a3225 100644 --- a/build/Install.ps1 +++ b/build/Install.ps1 @@ -3,16 +3,21 @@ param($installPath, $toolsPath, $package, $project) $appPluginsFolder = $project.ProjectItems | Where-Object { $_.Name -eq "App_Plugins" } $nestedContentFolder = $appPluginsFolder.ProjectItems | Where-Object { $_.Name -eq "NestedContent" } -$newPackageFiles = "$installPath\Content\App_Plugins\NestedContent" +if (!$nestedContentFolder) +{ + $newPackageFiles = "$installPath\Content\App_Plugins\NestedContent" -$projFile = Get-Item ($project.FullName) -$projDirectory = $projFile.DirectoryName -$projectPath = Join-Path $projDirectory -ChildPath "App_Plugins" -$projectPathExists = Test-Path $projectPath + $projFile = Get-Item ($project.FullName) + $projDirectory = $projFile.DirectoryName + $projectPath = Join-Path $projDirectory -ChildPath "App_Plugins" + $projectPathExists = Test-Path $projectPath -if ($projectPathExists -and !$nestedContentFolder) { - Write-Host "Updating Nested Content App_Plugin files using PS as they have been excluded from the project" - Copy-Item $newPackageFiles $projectPath -Recurse -Force + if ($projectPathExists) { + Write-Host "Updating Nested Content App_Plugin files using PS as they have been excluded from the project" + Copy-Item $newPackageFiles $projectPath -Recurse -Force + } } + + diff --git a/src/Our.Umbraco.NestedContent.sln b/src/Our.Umbraco.NestedContent.sln index b00a091..d5f896a 100644 --- a/src/Our.Umbraco.NestedContent.sln +++ b/src/Our.Umbraco.NestedContent.sln @@ -16,7 +16,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Package", "Build Pack ..\appveyor.yml = ..\appveyor.yml ..\build-appveyor.cmd = ..\build-appveyor.cmd ..\build.cmd = ..\build.cmd - ..\build\install.ps1 = ..\build\install.ps1 + ..\build\Install.ps1 = ..\build\Install.ps1 ..\build\package.nuspec = ..\build\package.nuspec ..\build\package.proj = ..\build\package.proj ..\build\package.xml = ..\build\package.xml From c35b2bf39b5678fd83a5e92b667cabae8b7cf483 Mon Sep 17 00:00:00 2001 From: Rasmus John Pedersen Date: Mon, 7 Sep 2015 15:02:51 +0200 Subject: [PATCH 09/41] Added support for doctype composition --- .../PropertyEditors/NestedContentPropertyEditor.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs b/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs index 6332798..8364f79 100644 --- a/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs +++ b/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs @@ -151,7 +151,7 @@ public override string ConvertDbToString(Property property, PropertyType propert foreach (var propKey in propValueKeys) { - var propType = contentType.PropertyTypes.FirstOrDefault(x => x.Alias == propKey); + var propType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propKey); if (propType == null) { if (IsSystemPropertyKey(propKey) == false) @@ -216,7 +216,7 @@ public override object ConvertDbToEditor(Property property, PropertyType propert foreach (var propKey in propValueKeys) { - var propType = contentType.PropertyTypes.FirstOrDefault(x => x.Alias == propKey); + var propType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propKey); if (propType == null) { if (IsSystemPropertyKey(propKey) == false) @@ -280,7 +280,7 @@ public override object ConvertEditorToDb(ContentPropertyData editorValue, object foreach (var propKey in propValueKeys) { - var propType = contentType.PropertyTypes.FirstOrDefault(x => x.Alias == propKey); + var propType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propKey); if (propType == null) { if (IsSystemPropertyKey(propKey) == false) @@ -342,7 +342,7 @@ public IEnumerable Validate(object rawValue, PreValueCollectio foreach (var propKey in propValueKeys) { - var propType = contentType.PropertyTypes.FirstOrDefault(x => x.Alias == propKey); + var propType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propKey); if (propType != null) { // It would be better to pass this off to the individual property editors From 1e32ffe222d5d9387b12d887ec0970c2d29855ff Mon Sep 17 00:00:00 2001 From: Rasmus John Pedersen Date: Wed, 23 Sep 2015 14:44:00 +0200 Subject: [PATCH 10/41] Added nested property editor validation support --- .../NestedContentPropertyEditor.cs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs b/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs index 6332798..5afde2a 100644 --- a/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs +++ b/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs @@ -327,6 +327,7 @@ public IEnumerable Validate(object rawValue, PreValueCollectio if (value == null) yield break; + IDataTypeService dataTypeService = ApplicationContext.Current.Services.DataTypeService; for (var i = 0; i < value.Count; i++) { var o = value[i]; @@ -345,15 +346,16 @@ public IEnumerable Validate(object rawValue, PreValueCollectio var propType = contentType.PropertyTypes.FirstOrDefault(x => x.Alias == propKey); if (propType != null) { - // It would be better to pass this off to the individual property editors - // to validate themselves and pass the result down, however a lot of the - // validation checking code in core seems to be internal so for now we'll - // just replicate the mandatory / regex validation checks ourselves. - // This does of course mean we will miss any custom validators a property - // editor may have registered by itself, and it also means we can only - // validate to a single depth so having a complex property editor in a - // doc type could get passed validation if it can't be validated from it's - // stored value alone. + PreValueCollection propPrevalues = dataTypeService.GetPreValuesCollectionByDataTypeId(propType.DataTypeDefinitionId); + PropertyEditor propertyEditor = PropertyEditorResolver.Current.GetByAlias(propType.PropertyEditorAlias); + + foreach (IPropertyValidator validator in propertyEditor.ValueEditor.Validators) + { + foreach (ValidationResult result in validator.Validate(propValues[propKey], propPrevalues, propertyEditor)) + { + yield return result; + } + } // Check mandatory if (propType.Mandatory) From f471cd551c42677db45635fdcd34f32f70c74dd9 Mon Sep 17 00:00:00 2001 From: Rasmus John Pedersen Date: Tue, 29 Sep 2015 14:08:35 +0200 Subject: [PATCH 11/41] Prefix validation message with property name. --- .../PropertyEditors/NestedContentPropertyEditor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs b/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs index 5afde2a..d8741d3 100644 --- a/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs +++ b/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs @@ -353,6 +353,7 @@ public IEnumerable Validate(object rawValue, PreValueCollectio { foreach (ValidationResult result in validator.Validate(propValues[propKey], propPrevalues, propertyEditor)) { + result.ErrorMessage = "Item " + (i + 1) + " '" + propType.Name + "' " + result.ErrorMessage; yield return result; } } From 07a00a8a6069928f34968a7358b5b6edcdb49117 Mon Sep 17 00:00:00 2001 From: Lee Kelleher Date: Thu, 8 Oct 2015 10:34:31 +0100 Subject: [PATCH 12/41] Update README.md Added known issue about Image Cropper data-type. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 75b81b5..9ec546c 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ A PDF download is also available: [Nested Content - Developers Guide v1.0.pdf](d Please be aware that not all property-editors will work within Nested Content. The following property-editors are known to have compatibility issues: * Upload (default Umbraco core) +* Image Cropper (default Umbraco core) * Macro Container (default Umbraco core) --- From b3cace1b5c15ba320ec62355fe7b4418a3629908 Mon Sep 17 00:00:00 2001 From: Simon Dingley Date: Tue, 10 Nov 2015 12:18:44 +0000 Subject: [PATCH 13/41] Fixes Issue #38 Returns null if there are no objects in the collection therefore not breaking recursive property lookups --- .../PropertyEditors/NestedContentPropertyEditor.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs b/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs index 8364f79..bde35e2 100644 --- a/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs +++ b/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs @@ -262,7 +262,11 @@ public override object ConvertEditorToDb(ContentPropertyData editorValue, object var value = JsonConvert.DeserializeObject>(editorValue.Value.ToString()); if (value == null) - return string.Empty; + return null; + + // Issue #38 - Keep recursive property lookups working + if (!value.Any()) + return null; // Process value for (var i = 0; i < value.Count; i++) From 22ecfa5587f95c4c3782b30fb411ee1ec619a634 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Sat, 28 Nov 2015 11:11:37 +0000 Subject: [PATCH 14/41] Updated directive to stash node context in scope so child scopes can have a way of detecting an inner node context from that stashed in editorState --- .../NestedContent/Js/nestedcontent.directives.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js index 08dfce2..6451a92 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js @@ -1,9 +1,9 @@ angular.module("umbraco.directives").directive('nestedContentEditor', [ - - function () { + "editorState", + function (editorState) { var link = function ($scope, element, attrs, ctrl) { - $scope.model = $scope.ngModel; + $scope.nodeContext = $scope.model = $scope.ngModel; var tab = $scope.ngModel.tabs[0]; From 3f3db6b1a67ff09b897027b7d20e2e3f8456afe2 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Sat, 28 Nov 2015 11:12:07 +0000 Subject: [PATCH 15/41] Didn't need to editorState injector --- .../App_Plugins/NestedContent/Js/nestedcontent.directives.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js index 6451a92..05d2407 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js @@ -1,6 +1,6 @@ angular.module("umbraco.directives").directive('nestedContentEditor', [ - "editorState", - function (editorState) { + + function () { var link = function ($scope, element, attrs, ctrl) { $scope.nodeContext = $scope.model = $scope.ngModel; From 61804487b2c27dbf6d7863d79f1540da14d1ce11 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Sat, 28 Nov 2015 11:15:41 +0000 Subject: [PATCH 16/41] switched to using ng-if for showing/hiding editors to help with performance (taken from PR #40) --- .../Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html index 5781bc9..deb5c97 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html @@ -25,7 +25,7 @@
    -
    +
    From 30a31b4e141f70f545db14a6301bbcd60e35b1b5 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Sat, 28 Nov 2015 16:27:57 +0000 Subject: [PATCH 17/41] Updated proj file --- .../Our.Umbraco.NestedContent.csproj | 6 +++--- src/Our.Umbraco.NestedContent/Properties/VersionInfo.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj b/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj index 238a18f..8bd1d51 100644 --- a/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj +++ b/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj @@ -257,9 +257,9 @@ IF %25ComputerName%25 == MBP13-PC-BC ( IF NOT "$(SolutionDir)" == "*Undefined*" ( - xcopy /s /y "$(TargetPath)" "C:\Users\Matt\Work\Sandbox\Umbraco\UmbracoCms.7.2.6\bin" - xcopy /s /y "$(TargetDir)$(ProjectName).pdb" "C:\Users\Matt\Work\Sandbox\Umbraco\UmbracoCms.7.2.6\bin" - xcopy /s /y "$(ProjectDir)Web\UI\*.*" "C:\Users\Matt\Work\Sandbox\Umbraco\UmbracoCms.7.2.6" + xcopy /s /y "$(TargetPath)" "C:\Users\Matt\Work\Sandbox\Umbraco\UmbracoUHangoutDemo\bin" + xcopy /s /y "$(TargetDir)$(ProjectName).pdb" "C:\Users\Matt\Work\Sandbox\Umbraco\UmbracoUHangoutDemo\bin" + xcopy /s /y "$(ProjectDir)Web\UI\*.*" "C:\Users\Matt\Work\Sandbox\Umbraco\UmbracoUHangoutDemo" ) ) diff --git a/src/Our.Umbraco.NestedContent/Properties/VersionInfo.cs b/src/Our.Umbraco.NestedContent/Properties/VersionInfo.cs index 96a08b4..ac9a194 100644 --- a/src/Our.Umbraco.NestedContent/Properties/VersionInfo.cs +++ b/src/Our.Umbraco.NestedContent/Properties/VersionInfo.cs @@ -13,7 +13,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -[assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyInformationalVersion("1.0.0-local-000100")] +[assembly: AssemblyVersion("0.2.*")] +[assembly: AssemblyInformationalVersion("0.2.1-dev-000100")] From a2e05bde2f3569f2ed61b75324a2bd3d0176ea89 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Sat, 28 Nov 2015 18:45:47 +0000 Subject: [PATCH 18/41] Implemented PR #22 and made nested content use formSubmiting handler to update it's model, rather than deep watching the nodes collection. This does mean the item labels don't update untill an item is closed, but it's better performance. --- .../Js/nestedcontent.controllers.js | 32 +++++++++++++++++-- .../Js/nestedcontent.directives.js | 25 +++++++++++++++ .../NestedContent/Views/nestedcontent.html | 4 ++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js index f2ac033..6ed1096 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js @@ -149,6 +149,9 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest }; $scope.editNode = function (idx) { + + $scope.$broadcast("formSubmitting", { scope: $scope }); + if ($scope.currentNode && $scope.currentNode.id == $scope.nodes[idx].id) { $scope.currentNode = undefined; } else { @@ -328,7 +331,7 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest return node; } - $scope.$watch("nodes", function () { + var updateModel = function () { if (inited) { var newValues = []; for (var i = 0; i < $scope.nodes.length; i++) { @@ -350,7 +353,32 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest } $scope.model.value = newValues; } - }, true); + } + + var unsubscribe = $scope.$on("formSubmitting", function (ev, args) { + updateModel(); + }); + + $scope.$on('$destroy', function () { + unsubscribe(); + }); + + // submit watcher handling: + // because some property editors use the "formSubmitting" event to set/clean up their model.value, + // we need to monitor the "formSubmitting" event from a custom property so we can update our model + // after all the children are done updating theirs. + + // A directive is added right after each node is rendered, and hooks into these callback methods. + // We have a counter so that the directive calling these methods can determine whether it's the one + // to trigger the onSubmit callback method or not, thereby making sure only the latest one triggers + // the update as all previous ones are going to be invalid. + $scope.activeSubmitWatcher = 0; + $scope.submitWatcherOnLoad = function () { + return ++$scope.activeSubmitWatcher; + } + $scope.submitWatcherOnSubmit = function () { + updateModel(); + } var guid = function () { function _p8(s) { diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js index 05d2407..b8b5d63 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js @@ -32,3 +32,28 @@ } ]); + +angular.module("umbraco.directives").directive('nestedContentSubmitWatcher', function () { + var link = function (scope) { + // call the load callback on scope to obtain the ID of this submit watcher + var id = scope.loadCallback(); + scope.$on("formSubmitting", function (ev, args) { + // on the "formSubmitting" event, call the submit callback on scope to notify the nestedContent controller to do it's magic + if (id === scope.activeSubmitWatcher) { + scope.submitCallback(); + } + }); + } + + return { + restrict: "E", + replace: true, + template: "", + scope: { + loadCallback: '=', + submitCallback: '=', + activeSubmitWatcher: '=' + }, + link: link + } +}); \ No newline at end of file diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html index deb5c97..d81b189 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html @@ -26,9 +26,11 @@
    - +
    + +
From c60b9bcaabd9c935079a992758c49b809f594d07 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Sat, 28 Nov 2015 18:50:59 +0000 Subject: [PATCH 19/41] Merged PR #31 --- .../Js/nestedcontent.controllers.js | 22 ++++++++++++++++++- .../NestedContent/Views/nestedcontent.html | 6 ++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js index 6ed1096..431253e 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js @@ -54,9 +54,10 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest "$interpolate", "$filter", "contentResource", + "localizationService", "Our.Umbraco.NestedContent.Resources.NestedContentResources", - function ($scope, $interpolate, $filter, contentResource, ncResources) { + function ($scope, $interpolate, $filter, contentResource, localizationService, ncResources) { //$scope.model.config.contentTypes; //$scope.model.config.minItems; @@ -71,6 +72,25 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest : undefined; }); + $scope.editIconTitle = ''; + $scope.moveIconTitle = ''; + $scope.deleteIconTitle = ''; + + // localize the edit icon title + localizationService.localize('general_edit').then(function (value) { + $scope.editIconTitle = value; + }); + + // localize the delete icon title + localizationService.localize('general_delete').then(function (value) { + $scope.deleteIconTitle = value; + }); + + // localize the move icon title + localizationService.localize('actions_move').then(function (value) { + $scope.moveIconTitle = value; + }); + $scope.nodes = []; $scope.currentNode = undefined; $scope.scaffolds = undefined; diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html index d81b189..1360131 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html @@ -12,13 +12,13 @@
From 272eec21bc3bdab034e6c87c24c253afecc967e1 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Sun, 29 Nov 2015 08:49:21 +0000 Subject: [PATCH 20/41] Changed how formSubmitting works so that we now just sync the value of the active node when the current editor closes or when saving --- .../Js/nestedcontent.controllers.js | 46 +++++++-------- .../Js/nestedcontent.directives.js | 56 +++++++++++-------- .../NestedContent/Views/nestedcontent.html | 9 +-- 3 files changed, 56 insertions(+), 55 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js index 431253e..7d0f005 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js @@ -93,6 +93,7 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest $scope.nodes = []; $scope.currentNode = undefined; + $scope.realCurrentNode = undefined; $scope.scaffolds = undefined; $scope.sorting = false; @@ -169,9 +170,6 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest }; $scope.editNode = function (idx) { - - $scope.$broadcast("formSubmitting", { scope: $scope }); - if ($scope.currentNode && $scope.currentNode.id == $scope.nodes[idx].id) { $scope.currentNode = undefined; } else { @@ -195,20 +193,25 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest var name = "Item " + (idx + 1); - var contentType = $scope.getContentTypeConfig($scope.model.value[idx].ncContentTypeAlias); + if ($scope.model.value[idx]) { - if (contentType != null && contentType.nameExp) { - var newName = contentType.nameExp($scope.model.value[idx]); // Run it against the stored dictionary value, NOT the node object - if (newName && (newName = $.trim(newName))) { - name = newName; + var contentType = $scope.getContentTypeConfig($scope.model.value[idx].ncContentTypeAlias); + + if (contentType != null && contentType.nameExp) { + var newName = contentType.nameExp($scope.model.value[idx]); // Run it against the stored dictionary value, NOT the node object + if (newName && (newName = $.trim(newName))) { + name = newName; + } } + } // Update the nodes actual name value - if ($scope.nodes[idx].name != newName) { + if ($scope.nodes[idx].name !== name) { $scope.nodes[idx].name = name; } + return name; }; @@ -352,6 +355,9 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest } var updateModel = function () { + if ($scope.realCurrentNode) { + $scope.$broadcast("ncSyncVal", { id: $scope.realCurrentNode.id }); + } if (inited) { var newValues = []; for (var i = 0; i < $scope.nodes.length; i++) { @@ -375,6 +381,11 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest } } + $scope.$watch("currentNode", function (newVal) { + updateModel(); + $scope.realCurrentNode = newVal; + }); + var unsubscribe = $scope.$on("formSubmitting", function (ev, args) { updateModel(); }); @@ -383,23 +394,6 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest unsubscribe(); }); - // submit watcher handling: - // because some property editors use the "formSubmitting" event to set/clean up their model.value, - // we need to monitor the "formSubmitting" event from a custom property so we can update our model - // after all the children are done updating theirs. - - // A directive is added right after each node is rendered, and hooks into these callback methods. - // We have a counter so that the directive calling these methods can determine whether it's the one - // to trigger the onSubmit callback method or not, thereby making sure only the latest one triggers - // the update as all previous ones are going to be invalid. - $scope.activeSubmitWatcher = 0; - $scope.submitWatcherOnLoad = function () { - return ++$scope.activeSubmitWatcher; - } - $scope.submitWatcherOnSubmit = function () { - updateModel(); - } - var guid = function () { function _p8(s) { var p = (Math.random().toString(16) + "000000000").substr(2, 8); diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js index b8b5d63..e70d238 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js @@ -17,6 +17,16 @@ } $scope.tab = tab; + + var unsubscribe = $scope.$on("ncSyncVal", function (ev, args) { + if (args.id === $scope.model.id) { + $scope.$broadcast("formSubmitting", { scope: $scope }); + } + }); + + $scope.$on('$destroy', function () { + unsubscribe(); + }); } return { @@ -33,27 +43,27 @@ } ]); -angular.module("umbraco.directives").directive('nestedContentSubmitWatcher', function () { - var link = function (scope) { - // call the load callback on scope to obtain the ID of this submit watcher - var id = scope.loadCallback(); - scope.$on("formSubmitting", function (ev, args) { - // on the "formSubmitting" event, call the submit callback on scope to notify the nestedContent controller to do it's magic - if (id === scope.activeSubmitWatcher) { - scope.submitCallback(); - } - }); - } +//angular.module("umbraco.directives").directive('nestedContentSubmitWatcher', function () { +// var link = function (scope) { +// // call the load callback on scope to obtain the ID of this submit watcher +// var id = scope.loadCallback(); +// scope.$on("formSubmitting", function (ev, args) { +// // on the "formSubmitting" event, call the submit callback on scope to notify the nestedContent controller to do it's magic +// if (id === scope.activeSubmitWatcher) { +// scope.submitCallback(); +// } +// }); +// } - return { - restrict: "E", - replace: true, - template: "", - scope: { - loadCallback: '=', - submitCallback: '=', - activeSubmitWatcher: '=' - }, - link: link - } -}); \ No newline at end of file +// return { +// restrict: "E", +// replace: true, +// template: "", +// scope: { +// loadCallback: '=', +// submitCallback: '=', +// activeSubmitWatcher: '=' +// }, +// link: link +// } +//}); \ No newline at end of file diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html index 1360131..cbff35d 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html @@ -5,14 +5,14 @@
-
+
From 1a95626679e9d241d26752a73279806b9726bca5 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Sun, 29 Nov 2015 08:53:14 +0000 Subject: [PATCH 21/41] Added updateModel call on sort finish event --- .../UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js index 7d0f005..63a37ef 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js @@ -241,6 +241,7 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest }); $scope.$apply(function () { $scope.sorting = false; + updateModel(); }); } }; From b5935a170d54ac1822ca8905ef0b391025382b31 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Sun, 29 Nov 2015 08:58:49 +0000 Subject: [PATCH 22/41] Improved a few css styles --- .../UI/App_Plugins/NestedContent/Css/nestedcontent.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css index 885efda..58db331 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css @@ -133,6 +133,10 @@ border-bottom: 1px dashed #e0e0e0; } +.nested-content__content .umb-control-group { + padding-bottom: 0; +} + .nested-content__item.ui-sortable-helper .nested-content__content { display: none !important; @@ -181,4 +185,8 @@ .form-horizontal .nested-content--narrow .controls-row .umb-textarea { width: 95%; +} + +.form-horizontal .nested-content--narrow .controls-row .umb-dropdown { + width: 99%; } \ No newline at end of file From 492a88b7ff37cf33a37b7ac0a390e18608f52db2 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Sun, 29 Nov 2015 09:26:50 +0000 Subject: [PATCH 23/41] Removed unused services js file --- src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj | 1 - .../UI/App_Plugins/NestedContent/Js/nestedcontent.services.js | 1 - .../Web/UI/App_Plugins/NestedContent/package.manifest | 1 - 3 files changed, 3 deletions(-) delete mode 100644 src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.services.js diff --git a/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj b/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj index 8bd1d51..5bae68b 100644 --- a/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj +++ b/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj @@ -243,7 +243,6 @@ - diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.services.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.services.js deleted file mode 100644 index 5f28270..0000000 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.services.js +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/package.manifest b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/package.manifest index f14d7ee..9e967b3 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/package.manifest +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/package.manifest @@ -1,7 +1,6 @@ { "javascript" : [ '~/App_Plugins/NestedContent/Js/nestedcontent.resources.js', - '~/App_Plugins/NestedContent/Js/nestedcontent.services.js', '~/App_Plugins/NestedContent/Js/nestedcontent.directives.js', '~/App_Plugins/NestedContent/Js/nestedcontent.controllers.js' ], From aa164aff0cc074acedd35af17013b9ec244f3cb9 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 30 Nov 2015 11:13:41 +0000 Subject: [PATCH 24/41] :neckbeard: Changed casing of "Install.ps1" to lowercase. --- build/{Install.ps1 => install.ps1} | 4 ---- build/package.proj | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) rename build/{Install.ps1 => install.ps1} (99%) diff --git a/build/Install.ps1 b/build/install.ps1 similarity index 99% rename from build/Install.ps1 rename to build/install.ps1 index 03a3225..d880df2 100644 --- a/build/Install.ps1 +++ b/build/install.ps1 @@ -17,7 +17,3 @@ if (!$nestedContentFolder) Copy-Item $newPackageFiles $projectPath -Recurse -Force } } - - - - diff --git a/build/package.proj b/build/package.proj index cd53a5d..e30d6d4 100644 --- a/build/package.proj +++ b/build/package.proj @@ -123,7 +123,7 @@ - + @@ -133,8 +133,8 @@ - - + + From 8270ef8aa6e7ca91d72289518e2c64194da5ec01 Mon Sep 17 00:00:00 2001 From: mattbrailsford Date: Tue, 8 Dec 2015 11:38:15 +0000 Subject: [PATCH 25/41] Few bug fixes --- .../UI/App_Plugins/NestedContent/Css/nestedcontent.css | 2 +- .../NestedContent/Js/nestedcontent.controllers.js | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css index 58db331..1d9cf8b 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css @@ -75,7 +75,7 @@ } .nested-content__header-bar:hover .nested-content__icons, -.nested-content__item--active .nested-content__icons +.nested-content__item--active > .nested-content__header-bar .nested-content__icons { opacity: 1; } diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js index 63a37ef..c5dad75 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js @@ -182,9 +182,11 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest if ($scope.model.config.confirmDeletes && $scope.model.config.confirmDeletes == 1) { if (confirm("Are you sure you want to delete this item?")) { $scope.nodes.splice(idx, 1); + updateModel(); } } else { $scope.nodes.splice(idx, 1); + updateModel(); } } }; @@ -335,6 +337,8 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest var tab = node.tabs[t]; for (var p = 0; p < tab.properties.length; p++) { var prop = tab.properties[p]; + prop.propertyAlias = prop.alias; + prop.alias = $scope.model.alias + "___" + prop.alias; // Force validation to occur server side as this is the // only way we can have consistancy between mandatory and // regex validation messages. Not ideal, but it works. @@ -343,8 +347,8 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest pattern: "" }; if (item) { - if (item[prop.alias]) { - prop.value = item[prop.alias]; + if (item[prop.propertyAlias]) { + prop.value = item[prop.propertyAlias]; } } } @@ -372,7 +376,7 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest for (var p = 0; p < tab.properties.length; p++) { var prop = tab.properties[p]; if (typeof prop.value !== "function") { - newValue[prop.alias] = prop.value; + newValue[prop.propertyAlias] = prop.value; } } } From fd1188b37d02bcaa7a577046a033128f1bd9c2e1 Mon Sep 17 00:00:00 2001 From: BatJan Date: Wed, 17 Feb 2016 13:45:21 +0100 Subject: [PATCH 26/41] Added "onDelayedMouseleave" directive The "delayedMouseLeave" directive has been renamed in Umbraco 7.4 to "onDelayedMouseleave" so I have added the new directive and left the old directive in there for backward compatibility reason. --- .../Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html index cbff35d..5194343 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html @@ -43,7 +43,7 @@
-
+
@@ -59,4 +59,4 @@
-
\ No newline at end of file +
From e956eecaaaff54c709d2a9d7fb3d071bf2ee00f7 Mon Sep 17 00:00:00 2001 From: Carl Jackson Date: Wed, 17 Feb 2016 13:06:22 +0000 Subject: [PATCH 27/41] add PropertyValueType attribute to help models builder #49 --- .../Converters/NestedContentValueConverter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs index 2f83a20..eb12ed1 100644 --- a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs +++ b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs @@ -17,6 +17,7 @@ namespace Our.Umbraco.NestedContent.Converters { [PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)] + [PropertyValueType(typeof(IEnumerable))] public class NestedContentValueConverter : PropertyValueConverterBase { private UmbracoHelper _umbraco; From cd9b7e24e5903edf4f271ea8005d0c9489eab89e Mon Sep 17 00:00:00 2001 From: Carl Jackson Date: Wed, 17 Feb 2016 13:07:10 +0000 Subject: [PATCH 28/41] add PropertyValueType attribute to help models builder #49 --- .../Converters/NestedContentValueConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs index eb12ed1..a6a59e2 100644 --- a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs +++ b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs @@ -17,7 +17,7 @@ namespace Our.Umbraco.NestedContent.Converters { [PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)] - [PropertyValueType(typeof(IEnumerable))] + [PropertyValueType(typeof(IEnumerable))] public class NestedContentValueConverter : PropertyValueConverterBase { private UmbracoHelper _umbraco; From b933f06e4d0df462d6a8013a5e1eed64f0b1e91e Mon Sep 17 00:00:00 2001 From: Carl Jackson Date: Wed, 17 Feb 2016 14:04:17 +0000 Subject: [PATCH 29/41] Create singleNestedContentPropertyConverter to handle when max and min items are set to 1. Also added 3 static extensions to PublishedPropertyType to stay DRY --- .../NestedContentConverterHelper.cs | 120 ++++++++++++++++++ .../Converters/NestedContentValueConverter.cs | 77 +---------- .../SingleNestedContentValueConverter.cs | 48 +++++++ .../Our.Umbraco.NestedContent.csproj | 2 + 4 files changed, 172 insertions(+), 75 deletions(-) create mode 100644 src/Our.Umbraco.NestedContent/Converters/NestedContentConverterHelper.cs create mode 100644 src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs diff --git a/src/Our.Umbraco.NestedContent/Converters/NestedContentConverterHelper.cs b/src/Our.Umbraco.NestedContent/Converters/NestedContentConverterHelper.cs new file mode 100644 index 0000000..ce3fc7d --- /dev/null +++ b/src/Our.Umbraco.NestedContent/Converters/NestedContentConverterHelper.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Our.Umbraco.NestedContent.Extensions; +using Our.Umbraco.NestedContent.Helpers; +using Our.Umbraco.NestedContent.Models; +using Our.Umbraco.NestedContent.PropertyEditors; +using Umbraco.Core; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Web; + +namespace Our.Umbraco.NestedContent.Converters +{ + public static class NestedContentConverterHelper + { + + public static bool IsNestedContentProperty(this PublishedPropertyType publishedProperty) + { + return publishedProperty.PropertyEditorAlias.InvariantEquals(NestedContentPropertyEditor.PropertyEditorAlias); + } + + public static bool IsSingleNestedContentProperty(this PublishedPropertyType publishedProperty) + { + if (!publishedProperty.IsNestedContentProperty()) + { + return false; + } + + var preValueCollection = NestedContentHelper.GetPreValuesCollectionByDataTypeId(publishedProperty.DataTypeId); + var preValueDictionary = preValueCollection.AsPreValueDictionary(); + + int minItems, maxItems; + return preValueDictionary.ContainsKey("minItems") && + int.TryParse(preValueDictionary["minItems"], out minItems) && minItems == 1 + && preValueDictionary.ContainsKey("maxItems") && + int.TryParse(preValueDictionary["maxItems"], out maxItems) && maxItems == 1; + } + + public static object ConvertDataToSource(this PublishedPropertyType propertyType, object source) + { + using (DisposableTimer.DebugDuration(string.Format("ConvertDataToSource ({0})", propertyType.DataTypeId))) + { + if (source != null && !source.ToString().IsNullOrWhiteSpace()) + { + var rawValue = JsonConvert.DeserializeObject>(source.ToString()); + var processedValue = new List(); + + var preValueCollection = NestedContentHelper.GetPreValuesCollectionByDataTypeId(propertyType.DataTypeId); + var preValueDictionary = preValueCollection.AsPreValueDictionary(); + + for (var i = 0; i < rawValue.Count; i++) + { + var item = (JObject)rawValue[i]; + + // Convert from old style (v.0.1.1) data format if necessary + // - Please note: This call has virtually no impact on rendering performance for new style (>v0.1.1). + // Even so, this should be removed eventually, when it's safe to assume that there is + // no longer any need for conversion. + NestedContentHelper.ConvertItemValueFromV011(item, propertyType.DataTypeId, ref preValueCollection); + + var contentTypeAlias = NestedContentHelper.GetContentTypeAliasFromItem(item); + if (string.IsNullOrEmpty(contentTypeAlias)) + { + continue; + } + + var publishedContentType = PublishedContentType.Get(PublishedItemType.Content, contentTypeAlias); + if (publishedContentType == null) + { + continue; + } + + var propValues = item.ToObject>(); + var properties = new List(); + + foreach (var jProp in propValues) + { + var propType = publishedContentType.GetPropertyType(jProp.Key); + if (propType != null) + { + properties.Add(new DetachedPublishedProperty(propType, jProp.Value)); + } + } + + // Parse out the name manually + object nameObj = null; + if (propValues.TryGetValue("name", out nameObj)) + { + // Do nothing, we just want to parse out the name if we can + } + + // Get the current request node we are embedded in + var pcr = UmbracoContext.Current.PublishedContentRequest; + var containerNode = pcr != null && pcr.HasPublishedContent ? pcr.PublishedContent : null; + + processedValue.Add(new DetachedPublishedContent( + nameObj == null ? null : nameObj.ToString(), + publishedContentType, + properties.ToArray(), + containerNode, + i)); + } + + if (propertyType.IsSingleNestedContentProperty()) + { + return processedValue.FirstOrDefault(); + } + + return processedValue; + } + } + return null; + } + } +} diff --git a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs index a6a59e2..d29e95c 100644 --- a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs +++ b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs @@ -28,87 +28,14 @@ internal UmbracoHelper Umbraco public override bool IsConverter(PublishedPropertyType propertyType) { - return propertyType.PropertyEditorAlias.InvariantEquals(NestedContentPropertyEditor.PropertyEditorAlias); + return propertyType.IsNestedContentProperty() && !propertyType.IsSingleNestedContentProperty(); } public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) { try { - using (DisposableTimer.DebugDuration(string.Format("ConvertDataToSource ({0})", propertyType.DataTypeId))) - { - if (source != null && !source.ToString().IsNullOrWhiteSpace()) - { - var rawValue = JsonConvert.DeserializeObject>(source.ToString()); - var processedValue = new List(); - - var preValueCollection = NestedContentHelper.GetPreValuesCollectionByDataTypeId(propertyType.DataTypeId); - var preValueDictionary = preValueCollection.AsPreValueDictionary(); - - for (var i = 0; i < rawValue.Count; i++) - { - var item = (JObject)rawValue[i]; - - // Convert from old style (v.0.1.1) data format if necessary - // - Please note: This call has virtually no impact on rendering performance for new style (>v0.1.1). - // Even so, this should be removed eventually, when it's safe to assume that there is - // no longer any need for conversion. - NestedContentHelper.ConvertItemValueFromV011(item, propertyType.DataTypeId, ref preValueCollection); - - var contentTypeAlias = NestedContentHelper.GetContentTypeAliasFromItem(item); - if (string.IsNullOrEmpty(contentTypeAlias)) - { - continue; - } - - var publishedContentType = PublishedContentType.Get(PublishedItemType.Content, contentTypeAlias); - if (publishedContentType == null) - { - continue; - } - - var propValues = item.ToObject>(); - var properties = new List(); - - foreach (var jProp in propValues) - { - var propType = publishedContentType.GetPropertyType(jProp.Key); - if (propType != null) - { - properties.Add(new DetachedPublishedProperty(propType, jProp.Value)); - } - } - - // Parse out the name manually - object nameObj = null; - if (propValues.TryGetValue("name", out nameObj)) - { - // Do nothing, we just want to parse out the name if we can - } - - // Get the current request node we are embedded in - var pcr = UmbracoContext.Current.PublishedContentRequest; - var containerNode = pcr != null && pcr.HasPublishedContent ? pcr.PublishedContent : null; - - processedValue.Add(new DetachedPublishedContent( - nameObj == null ? null : nameObj.ToString(), - publishedContentType, - properties.ToArray(), - containerNode, - i)); - } - - // Detect min/max items == 1 and just return a single IPublishedContent - int minItems, maxItems; - if (preValueDictionary.ContainsKey("minItems") && int.TryParse(preValueDictionary["minItems"], out minItems) && minItems == 1 - && preValueDictionary.ContainsKey("maxItems") && int.TryParse(preValueDictionary["maxItems"], out maxItems) && maxItems == 1) - { - return processedValue.FirstOrDefault(); - } - - return processedValue; - } - } + propertyType.ConvertDataToSource(source); } catch (Exception e) { diff --git a/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs new file mode 100644 index 0000000..a5bf386 --- /dev/null +++ b/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Our.Umbraco.NestedContent.Extensions; +using Our.Umbraco.NestedContent.Helpers; +using Our.Umbraco.NestedContent.Models; +using Our.Umbraco.NestedContent.PropertyEditors; +using Umbraco.Core; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.PropertyEditors; +using Umbraco.Web; + +namespace Our.Umbraco.NestedContent.Converters +{ + [PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)] + [PropertyValueType(typeof(IPublishedContent))] + public class SingleNestedContentValueConverter : PropertyValueConverterBase + { + private UmbracoHelper _umbraco; + internal UmbracoHelper Umbraco + { + get { return _umbraco ?? (_umbraco = new UmbracoHelper(UmbracoContext.Current)); } + } + + public override bool IsConverter(PublishedPropertyType propertyType) + { + return propertyType.IsSingleNestedContentProperty(); + } + + public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) + { + try + { + propertyType.ConvertDataToSource(source); + } + catch (Exception e) + { + LogHelper.Error("Error converting value", e); + } + + return null; + } + } +} \ No newline at end of file diff --git a/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj b/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj index 5bae68b..f4b1801 100644 --- a/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj +++ b/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj @@ -228,6 +228,8 @@ + + From 790a967114e2973818a9b9a4becda94742114500 Mon Sep 17 00:00:00 2001 From: Carl Jackson Date: Wed, 17 Feb 2016 14:13:44 +0000 Subject: [PATCH 30/41] rename extension method to something that makes sense --- .../Converters/NestedContentConverterHelper.cs | 2 +- .../Converters/NestedContentValueConverter.cs | 2 +- .../Converters/SingleNestedContentValueConverter.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Converters/NestedContentConverterHelper.cs b/src/Our.Umbraco.NestedContent/Converters/NestedContentConverterHelper.cs index ce3fc7d..9c90b59 100644 --- a/src/Our.Umbraco.NestedContent/Converters/NestedContentConverterHelper.cs +++ b/src/Our.Umbraco.NestedContent/Converters/NestedContentConverterHelper.cs @@ -41,7 +41,7 @@ public static bool IsSingleNestedContentProperty(this PublishedPropertyType publ int.TryParse(preValueDictionary["maxItems"], out maxItems) && maxItems == 1; } - public static object ConvertDataToSource(this PublishedPropertyType propertyType, object source) + public static object ConvertPropertyToNestedContent(this PublishedPropertyType propertyType, object source) { using (DisposableTimer.DebugDuration(string.Format("ConvertDataToSource ({0})", propertyType.DataTypeId))) { diff --git a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs index d29e95c..117b794 100644 --- a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs +++ b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs @@ -35,7 +35,7 @@ public override object ConvertDataToSource(PublishedPropertyType propertyType, o { try { - propertyType.ConvertDataToSource(source); + propertyType.ConvertPropertyToNestedContent(source); } catch (Exception e) { diff --git a/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs index a5bf386..f6d54db 100644 --- a/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs +++ b/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs @@ -35,7 +35,7 @@ public override object ConvertDataToSource(PublishedPropertyType propertyType, o { try { - propertyType.ConvertDataToSource(source); + propertyType.ConvertPropertyToNestedContent(source); } catch (Exception e) { From 6369e85f52b2a4b8b6eae2a8abd2cb5f1593fda3 Mon Sep 17 00:00:00 2001 From: Carl Jackson Date: Wed, 17 Feb 2016 14:28:45 +0000 Subject: [PATCH 31/41] add in missing return statement --- .../Converters/NestedContentValueConverter.cs | 2 +- .../Converters/SingleNestedContentValueConverter.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs index 117b794..aaf0324 100644 --- a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs +++ b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs @@ -35,7 +35,7 @@ public override object ConvertDataToSource(PublishedPropertyType propertyType, o { try { - propertyType.ConvertPropertyToNestedContent(source); + return propertyType.ConvertPropertyToNestedContent(source); } catch (Exception e) { diff --git a/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs index f6d54db..1703945 100644 --- a/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs +++ b/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs @@ -35,7 +35,7 @@ public override object ConvertDataToSource(PublishedPropertyType propertyType, o { try { - propertyType.ConvertPropertyToNestedContent(source); + return propertyType.ConvertPropertyToNestedContent(source); } catch (Exception e) { From aac85fab64d798f03b69df374b8223332812df21 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 31 Mar 2016 13:04:04 +0100 Subject: [PATCH 32/41] AppVeyor: Added MyGet deploy for new feed. Bumped version number v0.3.0 --- appveyor.yml | 18 ++++++++++++++---- .../Properties/VersionInfo.cs | 6 +++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 601a746..e09e55c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,5 @@ # version format -version: 0.2.0.{build} +version: 0.3.0.{build} # UMBRACO_PACKAGE_PRERELEASE_SUFFIX if a rtm release build this should be blank, otherwise if empty will default to alpha # example UMBRACO_PACKAGE_PRERELEASE_SUFFIX=beta @@ -14,7 +14,7 @@ artifacts: - path: artifacts\*.zip deploy: - # MyGet Deployment for builds & releases + # MyGet Deployment for builds & releases - provider: NuGet server: https://www.myget.org/F/umbraco-nested-content/ symbol_server: https://nuget.symbolsource.org/MyGet/umbraco-nested-content @@ -24,7 +24,17 @@ deploy: on: branch: develop - # GitHub Deployment for releases + # MyGet Deployment for builds & releases + - provider: NuGet + server: https://www.myget.org/F/umbraco-packages/ + symbol_server: https://nuget.symbolsource.org/MyGet/umbraco-packages + api_key: + secure: Q1/4K8VSwr7BjwmKDTef8y5lOc7S+jK9ELuWy67y6OVRpjxmnF9M3Gfs1kT+ir8x + artifact: /.*\.nupkg/ + on: + branch: develop + + # GitHub Deployment for releases - provider: GitHub auth_token: secure: pEozEGTqJutQwOidJU6BTB+Ix0NV4vrUnomhfeqheVz4RNwfxjEYLoqR4XabhlPz @@ -35,7 +45,7 @@ deploy: branch: master appveyor_repo_tag: true # deploy on tag push only - # NuGet Deployment for releases + # NuGet Deployment for releases - provider: NuGet server: api_key: diff --git a/src/Our.Umbraco.NestedContent/Properties/VersionInfo.cs b/src/Our.Umbraco.NestedContent/Properties/VersionInfo.cs index ac9a194..90d688c 100644 --- a/src/Our.Umbraco.NestedContent/Properties/VersionInfo.cs +++ b/src/Our.Umbraco.NestedContent/Properties/VersionInfo.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34209 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -13,7 +13,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -[assembly: AssemblyVersion("0.2.*")] -[assembly: AssemblyInformationalVersion("0.2.1-dev-000100")] +[assembly: AssemblyVersion("0.3.*")] +[assembly: AssemblyInformationalVersion("0.3.0-develop")] From 418c9bf6152bb5286ad2eac9ea5d6b351b597ab4 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 31 Mar 2016 13:04:47 +0100 Subject: [PATCH 33/41] Added SQL snippet example To help if someone needed to rename a DocType or property alias. --- .../NC_RENAME_DOCTYPE_OR_PROPERTY_ALIAS.sql | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 docs/code-snippets/NC_RENAME_DOCTYPE_OR_PROPERTY_ALIAS.sql diff --git a/docs/code-snippets/NC_RENAME_DOCTYPE_OR_PROPERTY_ALIAS.sql b/docs/code-snippets/NC_RENAME_DOCTYPE_OR_PROPERTY_ALIAS.sql new file mode 100644 index 0000000..8e2631d --- /dev/null +++ b/docs/code-snippets/NC_RENAME_DOCTYPE_OR_PROPERTY_ALIAS.sql @@ -0,0 +1,29 @@ +-- # Nested Content SQL scripts + +-- ## Renaming a DocType alias + +UPDATE + cmsPropertyData +SET + dataNtext = CAST(REPLACE(CAST(dataNtext AS nvarchar(max)), '"ncContentTypeAlias":"OLD_ALIAS"', '"ncContentTypeAlias":"NEW_ALIAS"') AS ntext) +WHERE + dataNtext LIKE '%"ncContentTypeAlias":"OLD_ALIAS"%' +; + +UPDATE + cmsDataTypePreValues +SET + [value] = CAST(REPLACE(CAST([value] AS nvarchar(max)), '"ncAlias": "OLD_ALIAS"', '"ncAlias": "NEW_ALIAS"') AS ntext) +WHERE + [value] LIKE '%"ncAlias": "OLD_ALIAS"%' +; + +-- ## Renaming a property alias + +UPDATE + cmsPropertyData +SET + dataNtext = CAST(REPLACE(CAST(dataNtext AS nvarchar(max)), ',"OLD_ALIAS":', ',"NEW_ALIAS":') AS ntext) +WHERE + dataNtext LIKE '%"ncContentTypeAlias":"CONTENT_TYPE_ALIAS"%' +; From 45960c9db65b89aed171e15fb4624eb0ef2e59c1 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 31 Mar 2016 13:08:28 +0100 Subject: [PATCH 34/41] Updated README Updated link for MyGet package feed repo + explanation of feeds in appveyor.yml --- README.md | 2 +- appveyor.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9ec546c..1fd9e7a 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ To [install from NuGet](https://www.nuget.org/packages/Our.Umbraco.NestedContent PM> Install-Package Our.Umbraco.NestedContent -We also have a [MyGet package repository](https://www.myget.org/gallery/umbraco-nested-content) - for bleeding-edge / development releases. +We also have a [MyGet package repository](https://www.myget.org/gallery/umbraco-packages) - for bleeding-edge / development releases. #### Manual build diff --git a/appveyor.yml b/appveyor.yml index e09e55c..13f93a2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,7 +14,7 @@ artifacts: - path: artifacts\*.zip deploy: - # MyGet Deployment for builds & releases + # MyGet (Nested Content feed) Deployment for builds & releases - provider: NuGet server: https://www.myget.org/F/umbraco-nested-content/ symbol_server: https://nuget.symbolsource.org/MyGet/umbraco-nested-content @@ -24,7 +24,7 @@ deploy: on: branch: develop - # MyGet Deployment for builds & releases + # MyGet (Umbraco Community feed) Deployment for builds & releases - provider: NuGet server: https://www.myget.org/F/umbraco-packages/ symbol_server: https://nuget.symbolsource.org/MyGet/umbraco-packages From 79980acdb863d180242132be86fa9394e827e152 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 31 Mar 2016 13:12:12 +0100 Subject: [PATCH 35/41] AppVeyor: Added NuGet package cache [skip ci] --- appveyor.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 13f93a2..6cfa984 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,6 +6,9 @@ version: 0.3.0.{build} init: - set UMBRACO_PACKAGE_PRERELEASE_SUFFIX= +cache: + - src\packages -> **\packages.config # preserve "packages" directory in the root of build folder but will reset it if packages.config is modified + build_script: - build-appveyor.cmd From afee76284644fe57e052ff3175d04a401b5b9b6d Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 7 Apr 2016 22:18:39 +0100 Subject: [PATCH 36/41] Moved the `NestedContentConverterHelper` class to the extension methods namespace and renamed to `PublishedPropertyTypeExtensions`. Removed the `UmbracoHelper` from the property-value converters, as it was never being used/referenced. Added ".vs" folder to the git ignore rules. --- .gitignore | 1 + .../Converters/NestedContentValueConverter.cs | 16 +--------------- .../SingleNestedContentValueConverter.cs | 17 +---------------- .../PublishedPropertyTypeExtensions.cs} | 16 ++++++---------- .../Our.Umbraco.NestedContent.csproj | 2 +- .../Properties/AssemblyInfo.cs | 1 - .../NestedContentPropertyEditor.cs | 6 ++---- 7 files changed, 12 insertions(+), 47 deletions(-) rename src/Our.Umbraco.NestedContent/{Converters/NestedContentConverterHelper.cs => Extensions/PublishedPropertyTypeExtensions.cs} (92%) diff --git a/.gitignore b/.gitignore index c9b8ca7..181c0f5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ _ReSharper.* Thumbs.db .DS_Store *.log +.vs artifacts/ src/packages/*/** diff --git a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs index aaf0324..853781c 100644 --- a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs +++ b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs @@ -1,31 +1,17 @@ using System; using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Our.Umbraco.NestedContent.Extensions; -using Our.Umbraco.NestedContent.Helpers; -using Our.Umbraco.NestedContent.Models; -using Our.Umbraco.NestedContent.PropertyEditors; -using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; -using Umbraco.Web; namespace Our.Umbraco.NestedContent.Converters { [PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)] - [PropertyValueType(typeof(IEnumerable))] + [PropertyValueType(typeof(IEnumerable))] public class NestedContentValueConverter : PropertyValueConverterBase { - private UmbracoHelper _umbraco; - internal UmbracoHelper Umbraco - { - get { return _umbraco ?? (_umbraco = new UmbracoHelper(UmbracoContext.Current)); } - } - public override bool IsConverter(PublishedPropertyType propertyType) { return propertyType.IsNestedContentProperty() && !propertyType.IsSingleNestedContentProperty(); diff --git a/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs index 1703945..7dd66ee 100644 --- a/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs +++ b/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs @@ -1,31 +1,16 @@ using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Our.Umbraco.NestedContent.Extensions; -using Our.Umbraco.NestedContent.Helpers; -using Our.Umbraco.NestedContent.Models; -using Our.Umbraco.NestedContent.PropertyEditors; -using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; -using Umbraco.Web; namespace Our.Umbraco.NestedContent.Converters { [PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)] - [PropertyValueType(typeof(IPublishedContent))] + [PropertyValueType(typeof(IPublishedContent))] public class SingleNestedContentValueConverter : PropertyValueConverterBase { - private UmbracoHelper _umbraco; - internal UmbracoHelper Umbraco - { - get { return _umbraco ?? (_umbraco = new UmbracoHelper(UmbracoContext.Current)); } - } - public override bool IsConverter(PublishedPropertyType propertyType) { return propertyType.IsSingleNestedContentProperty(); diff --git a/src/Our.Umbraco.NestedContent/Converters/NestedContentConverterHelper.cs b/src/Our.Umbraco.NestedContent/Extensions/PublishedPropertyTypeExtensions.cs similarity index 92% rename from src/Our.Umbraco.NestedContent/Converters/NestedContentConverterHelper.cs rename to src/Our.Umbraco.NestedContent/Extensions/PublishedPropertyTypeExtensions.cs index 9c90b59..88694dd 100644 --- a/src/Our.Umbraco.NestedContent/Converters/NestedContentConverterHelper.cs +++ b/src/Our.Umbraco.NestedContent/Extensions/PublishedPropertyTypeExtensions.cs @@ -1,11 +1,7 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Our.Umbraco.NestedContent.Extensions; using Our.Umbraco.NestedContent.Helpers; using Our.Umbraco.NestedContent.Models; using Our.Umbraco.NestedContent.PropertyEditors; @@ -14,11 +10,10 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Web; -namespace Our.Umbraco.NestedContent.Converters +namespace Our.Umbraco.NestedContent.Extensions { - public static class NestedContentConverterHelper + internal static class PublishedPropertyTypeExtensions { - public static bool IsNestedContentProperty(this PublishedPropertyType publishedProperty) { return publishedProperty.PropertyEditorAlias.InvariantEquals(NestedContentPropertyEditor.PropertyEditorAlias); @@ -43,7 +38,7 @@ public static bool IsSingleNestedContentProperty(this PublishedPropertyType publ public static object ConvertPropertyToNestedContent(this PublishedPropertyType propertyType, object source) { - using (DisposableTimer.DebugDuration(string.Format("ConvertDataToSource ({0})", propertyType.DataTypeId))) + using (DisposableTimer.DebugDuration(string.Format("ConvertPropertyToNestedContent ({0})", propertyType.DataTypeId))) { if (source != null && !source.ToString().IsNullOrWhiteSpace()) { @@ -114,7 +109,8 @@ public static object ConvertPropertyToNestedContent(this PublishedPropertyType p return processedValue; } } + return null; } } -} +} \ No newline at end of file diff --git a/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj b/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj index f4b1801..1f75b5e 100644 --- a/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj +++ b/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj @@ -228,7 +228,7 @@ - + diff --git a/src/Our.Umbraco.NestedContent/Properties/AssemblyInfo.cs b/src/Our.Umbraco.NestedContent/Properties/AssemblyInfo.cs index 231ac6e..efdad60 100644 --- a/src/Our.Umbraco.NestedContent/Properties/AssemblyInfo.cs +++ b/src/Our.Umbraco.NestedContent/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; [assembly: AssemblyTitle("Our.Umbraco.NestedContent")] diff --git a/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs b/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs index 9ebc5c1..e1d33fa 100644 --- a/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs +++ b/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs @@ -1,7 +1,6 @@ -using System; -using System.Linq; -using System.Collections.Generic; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Linq; using System.Text.RegularExpressions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -12,7 +11,6 @@ using Umbraco.Core.Models.Editors; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; -using umbraco.editorControls.SettingControls; using Umbraco.Web.PropertyEditors; namespace Our.Umbraco.NestedContent.PropertyEditors From 028f1700ebfd75d928496c7a6d26c90a4720cf82 Mon Sep 17 00:00:00 2001 From: dipeshhirani Date: Fri, 15 Apr 2016 17:13:09 +0100 Subject: [PATCH 37/41] Update nestedcontent.css removed 30% width for label --- .../Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css index 1d9cf8b..809119f 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Css/nestedcontent.css @@ -171,11 +171,6 @@ margin-left: 10px; } -.form-horizontal .nested-content--narrow .control-label -{ - width: 30%; -} - .form-horizontal .nested-content--narrow .controls-row { margin-left: 40% !important; @@ -189,4 +184,4 @@ .form-horizontal .nested-content--narrow .controls-row .umb-dropdown { width: 99%; -} \ No newline at end of file +} From 822dd93c26a1dc1f1458e8f9cb4cf4eaa006983b Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 30 Jun 2016 14:22:11 +0100 Subject: [PATCH 38/41] Added `strict` attribute to the package.xml This is to support future versions of Umbraco (v7.5+) --- build/package.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/package.xml b/build/package.xml index c77d85c..8214488 100644 --- a/build/package.xml +++ b/build/package.xml @@ -6,7 +6,7 @@ 0.0.0 - + 0 0 0 From 7b5e34ebe67e98848faca2d8204d0f4f67271178 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 30 Jun 2016 14:22:34 +0100 Subject: [PATCH 39/41] Minor amends to CONTRIBUTING --- CONTRIBUTING.md | 4 ++-- src/Our.Umbraco.NestedContent.sln | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2bfb43c..4720c98 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,8 +36,8 @@ Guidelines for bug reports: 2. **Check if the issue has been fixed** — try to reproduce it using the latest `master` or development branch in the repository. -3. **Isolate the problem** — create a [reduced test - case](http://css-tricks.com/6263-reduced-test-cases/) and a live example. +3. **Isolate the problem** — create a reduced test + case and a live example. A good bug report shouldn't leave others needing to chase you up for more information. Please try to be as detailed as possible in your report. What is diff --git a/src/Our.Umbraco.NestedContent.sln b/src/Our.Umbraco.NestedContent.sln index d5f896a..b00a091 100644 --- a/src/Our.Umbraco.NestedContent.sln +++ b/src/Our.Umbraco.NestedContent.sln @@ -16,7 +16,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Package", "Build Pack ..\appveyor.yml = ..\appveyor.yml ..\build-appveyor.cmd = ..\build-appveyor.cmd ..\build.cmd = ..\build.cmd - ..\build\Install.ps1 = ..\build\Install.ps1 + ..\build\install.ps1 = ..\build\install.ps1 ..\build\package.nuspec = ..\build\package.nuspec ..\build\package.proj = ..\build\package.proj ..\build\package.xml = ..\build\package.xml From 48f69f60d6fc7ee7a4f1f3858855bc77ded76cf2 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 30 Jun 2016 15:07:18 +0100 Subject: [PATCH 40/41] Updated README with more known issues. --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1fd9e7a..b2a3050 100644 --- a/README.md +++ b/README.md @@ -57,9 +57,12 @@ A PDF download is also available: [Nested Content - Developers Guide v1.0.pdf](d Please be aware that not all property-editors will work within Nested Content. The following property-editors are known to have compatibility issues: -* Upload (default Umbraco core) +* Checkbox List (default Umbraco core) * Image Cropper (default Umbraco core) * Macro Container (default Umbraco core) +* Radiobutton List (default Umbraco core) +* Repeatable Textstring (default Umbraco core) - this works in the back-office, but due to a bug in the value-converter it will produce additional blank entries +* Upload (default Umbraco core) --- From bdb8f5c2ff9ad87a02dd21bcbfd91edb4d8fe3c5 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 7 Jul 2016 19:17:25 +0100 Subject: [PATCH 41/41] Removed leading whitespace on icon's CSS class --- .../Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html index 5194343..0943780 100644 --- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html +++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html @@ -38,7 +38,7 @@