From 763220f3dac054868882af16367676c48182977f Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 22 Jan 2019 17:16:17 -0800 Subject: [PATCH 01/11] POC: Swap 'Doc Type Picker' with List View's layout control --- .../InnerContent/css/innercontent.css | 13 +--- .../InnerContent/js/innercontent.js | 44 +++++++++++- .../views/innercontent.doctypepicker.html | 68 +++++++++---------- 3 files changed, 76 insertions(+), 49 deletions(-) diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/css/innercontent.css b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/css/innercontent.css index 5fe1ff7..84751ef 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/css/innercontent.css +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/css/innercontent.css @@ -1,26 +1,19 @@ /* Inner Content - Doc Type Picker */ -.inner-content__doctypepicker table input, -.inner-content__doctypepicker table select { - width: 100%; - padding-right: 0; +.inner-content__doctypepicker .inner-content__help-container { + text-align: right; + margin-bottom: .5em; } -.inner-content__doctypepicker table td.icon-navigation, .inner-content__doctypepicker i.inner-content__help-icon { vertical-align: middle; color: #CCC; } -.inner-content__doctypepicker table td.icon-navigation:hover, .inner-content__doctypepicker i.inner-content__help-icon:hover { color: #343434; } -.inner-content__doctypepicker table .td-min { - width: 1px; -} - /* Inner Content - Content Overlay Panel */ diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js index 6147182..34cf228 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js @@ -7,10 +7,14 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy function ($scope, innerContentService) { var vm = this; + vm.docTypes = []; + vm.selectedDocTypes = []; vm.add = add; vm.remove = remove; vm.tooltipMouseOver = tooltipMouseOver; vm.tooltipMouseLeave = tooltipMouseLeave; + vm.getContentType = getContentType; + vm.openDocTypePicker = openDocTypePicker; vm.sortableOptions = { axis: "y", @@ -33,23 +37,26 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy innerContentService.getAllContentTypes().then(function (docTypes) { vm.docTypes = docTypes; + updateSelectedDocTypes(); }); if (!$scope.model.value) { $scope.model.value = []; - add(); } function add() { - $scope.model.value.push({ + var newItem = { icContentTypeGuid: "", nameTemplate: "" - }); + }; + $scope.model.value.push(newItem); + openDocTypePicker(newItem); setDirty(); }; function remove(index) { $scope.model.value.splice(index, 1); + updateSelectedDocTypes(); setDirty(); }; @@ -69,6 +76,37 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy }; }; + function updateSelectedDocTypes() { + vm.selectedDocTypes = _.filter(vm.docTypes, function (i) { + var match = _.find($scope.model.value, function (c) { + return c.icContentTypeGuid === i.guid; + }); + + return match !== undefined; + }); + }; + + function getContentType(guid) { + return _.find(vm.docTypes, function (d) { + return d.guid === guid; + }); + }; + + function openDocTypePicker(config) { + vm.docTypePicker = { + view: "itempicker", + availableItems: vm.docTypes, + selectedItems: vm.selectedDocTypes, + show: true, + submit: function (model) { + config.icContentTypeGuid = model.selectedItem.guid; + updateSelectedDocTypes(); + vm.docTypePicker.show = false; + vm.docTypePicker = null; + } + }; + }; + function setDirty() { if ($scope.propertyForm) { $scope.propertyForm.$setDirty(); diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.doctypepicker.html b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.doctypepicker.html index 8c4fd03..561f9cd 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.doctypepicker.html +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.doctypepicker.html @@ -1,42 +1,38 @@ 
-
- - - - - - - - - - - - - - - -
- - Document Type - - Name Template - - -
- - - - - Remove -
-
- Add +
+ +
+
+
+ +
+ + + +
+
+ {{ vm.getContentType(config.icContentTypeGuid).name || 'Name' }} + ({{ vm.getContentType(config.icContentTypeGuid).alias || 'alias' }}) +
+
+ +
+
+
+ +
+
+ Add Content Type
+ + {{vm.tooltip.content}} From 8c51eba435ef4b086ddac2754e38ab63981c63f5 Mon Sep 17 00:00:00 2001 From: Dan White Date: Thu, 25 Jul 2019 16:21:10 -0700 Subject: [PATCH 02/11] Create build process for Azure Pipelines Attempt to use env variables in cmd Fix typo Attempt to pass variables to cmd Pass env variables to cmd Set variables instead of just echo TYPO Echo out variable values Try echoing values of set variables Try using BuildId Remove spaces from variable sets Add suffix Add LCSC as suffix Publish artifacts --- azure-pipelines.yml | 26 ++++++++++++++++++++++++++ build-pipelines.cmd | 13 +++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 azure-pipelines.yml create mode 100644 build-pipelines.cmd diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..87ddae6 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,26 @@ +trigger: +- master + +pool: + vmImage: 'vs2017-win2016' + +variables: + version: 2.0.5.$(Build.BuildId) + +steps: +- task: CmdLine@2 + displayName: 'Build Packages' + inputs: + script: 'build-pipelines.cmd' + env: + BranchName: $(Build.SourceBranchName) + Version: $(version) + BuildNumber: $(Build.BuildId) + Tag: false + Suffix: 'lcsc' + +- task: PublishBuildArtifacts@1 + inputs: + PathtoPublish: 'artifacts' + ArtifactName: 'drop' + publishLocation: 'Container' \ No newline at end of file diff --git a/build-pipelines.cmd b/build-pipelines.cmd new file mode 100644 index 0000000..738b68b --- /dev/null +++ b/build-pipelines.cmd @@ -0,0 +1,13 @@ +SET APPVEYOR_REPO_BRANCH=%BRANCHNAME% +SET APPVEYOR_REPO_TAG=%TAG% +SET APPVEYOR_BUILD_NUMBER=%BUILDNUMBER% +SET APPVEYOR_BUILD_VERSION=%VERSION% +SET UMBRACO_PACKAGE_PRERELEASE_SUFFIX=%SUFFIX% + +ECHO APPVEYOR_REPO_BRANCH : %APPVEYOR_REPO_BRANCH% +ECHO APPVEYOR_REPO_TAG : %APPVEYOR_REPO_TAG% +ECHO APPVEYOR_BUILD_NUMBER : %APPVEYOR_BUILD_NUMBER% +ECHO APPVEYOR_BUILD_VERSION : %APPVEYOR_BUILD_VERSION% + +CALL build\tools\NuGet\NuGet.exe restore src\Our.Umbraco.InnerContent.sln +CALL "%programfiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\amd64\MsBuild.exe" build\package.proj \ No newline at end of file From 07eb44c6ec9b2bb62bd8e80f999df3a8194437a2 Mon Sep 17 00:00:00 2001 From: Dan White Date: Thu, 25 Jul 2019 16:30:22 -0700 Subject: [PATCH 03/11] Add new files to solution items --- src/Our.Umbraco.InnerContent.sln | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Our.Umbraco.InnerContent.sln b/src/Our.Umbraco.InnerContent.sln index fa87552..9c851ab 100644 --- a/src/Our.Umbraco.InnerContent.sln +++ b/src/Our.Umbraco.InnerContent.sln @@ -15,7 +15,9 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Scripts", "Build Scripts", "{0EDC340A-DCE2-459A-9114-99B7334A1D2D}" ProjectSection(SolutionItems) = preProject ..\appveyor.yml = ..\appveyor.yml + ..\azure-pipelines.yml = ..\azure-pipelines.yml ..\build-appveyor.cmd = ..\build-appveyor.cmd + ..\build-pipelines.cmd = ..\build-pipelines.cmd ..\build.cmd = ..\build.cmd ..\build\install.ps1 = ..\build\install.ps1 ..\build\package.core.nuspec = ..\build\package.core.nuspec From e5d747363b60d85bdada1d6c1764d2705b9ac860 Mon Sep 17 00:00:00 2001 From: Dan White Date: Thu, 25 Jul 2019 16:50:54 -0700 Subject: [PATCH 04/11] Don't add new type to model until after a doctype is selected --- .../Web/UI/App_Plugins/InnerContent/js/innercontent.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js index 3d2ee27..1d0c83c 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js @@ -1,4 +1,4 @@ -// Prevalue Editors +// Prevalue Editors angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTypePickerController", [ "$scope", @@ -49,7 +49,6 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy icContentTypeGuid: "", nameTemplate: "" }; - $scope.model.value.push(newItem); openDocTypePicker(newItem); setDirty(); }; @@ -100,6 +99,8 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy show: true, submit: function (model) { config.icContentTypeGuid = model.selectedItem.guid; + $scope.model.value.push(config); + updateSelectedDocTypes(); vm.docTypePicker.show = false; vm.docTypePicker = null; From 12ebc04086e79343597d3a9958d54a2bc4cffdc5 Mon Sep 17 00:00:00 2001 From: Dan White Date: Thu, 25 Jul 2019 17:02:17 -0700 Subject: [PATCH 05/11] Drop doctype alias to new line --- .../Web/UI/App_Plugins/InnerContent/css/innercontent.css | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/css/innercontent.css b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/css/innercontent.css index 84751ef..7a02751 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/css/innercontent.css +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/css/innercontent.css @@ -10,10 +10,13 @@ color: #CCC; } -.inner-content__doctypepicker i.inner-content__help-icon:hover { - color: #343434; -} + .inner-content__doctypepicker i.inner-content__help-icon:hover { + color: #343434; + } +.inner-content__doctypepicker .list-view-layout__system { + width: 100%; +} /* Inner Content - Content Overlay Panel */ From 5949b6babd35a62782b47a0fcfb786a65a61134c Mon Sep 17 00:00:00 2001 From: Dan White Date: Thu, 25 Jul 2019 17:07:54 -0700 Subject: [PATCH 06/11] Remove files from unrelated branch --- azure-pipelines.yml | 26 -------------------------- build-pipelines.cmd | 13 ------------- src/Our.Umbraco.InnerContent.sln | 2 -- 3 files changed, 41 deletions(-) delete mode 100644 azure-pipelines.yml delete mode 100644 build-pipelines.cmd diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index 87ddae6..0000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,26 +0,0 @@ -trigger: -- master - -pool: - vmImage: 'vs2017-win2016' - -variables: - version: 2.0.5.$(Build.BuildId) - -steps: -- task: CmdLine@2 - displayName: 'Build Packages' - inputs: - script: 'build-pipelines.cmd' - env: - BranchName: $(Build.SourceBranchName) - Version: $(version) - BuildNumber: $(Build.BuildId) - Tag: false - Suffix: 'lcsc' - -- task: PublishBuildArtifacts@1 - inputs: - PathtoPublish: 'artifacts' - ArtifactName: 'drop' - publishLocation: 'Container' \ No newline at end of file diff --git a/build-pipelines.cmd b/build-pipelines.cmd deleted file mode 100644 index 738b68b..0000000 --- a/build-pipelines.cmd +++ /dev/null @@ -1,13 +0,0 @@ -SET APPVEYOR_REPO_BRANCH=%BRANCHNAME% -SET APPVEYOR_REPO_TAG=%TAG% -SET APPVEYOR_BUILD_NUMBER=%BUILDNUMBER% -SET APPVEYOR_BUILD_VERSION=%VERSION% -SET UMBRACO_PACKAGE_PRERELEASE_SUFFIX=%SUFFIX% - -ECHO APPVEYOR_REPO_BRANCH : %APPVEYOR_REPO_BRANCH% -ECHO APPVEYOR_REPO_TAG : %APPVEYOR_REPO_TAG% -ECHO APPVEYOR_BUILD_NUMBER : %APPVEYOR_BUILD_NUMBER% -ECHO APPVEYOR_BUILD_VERSION : %APPVEYOR_BUILD_VERSION% - -CALL build\tools\NuGet\NuGet.exe restore src\Our.Umbraco.InnerContent.sln -CALL "%programfiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\amd64\MsBuild.exe" build\package.proj \ No newline at end of file diff --git a/src/Our.Umbraco.InnerContent.sln b/src/Our.Umbraco.InnerContent.sln index 9c851ab..fa87552 100644 --- a/src/Our.Umbraco.InnerContent.sln +++ b/src/Our.Umbraco.InnerContent.sln @@ -15,9 +15,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Scripts", "Build Scripts", "{0EDC340A-DCE2-459A-9114-99B7334A1D2D}" ProjectSection(SolutionItems) = preProject ..\appveyor.yml = ..\appveyor.yml - ..\azure-pipelines.yml = ..\azure-pipelines.yml ..\build-appveyor.cmd = ..\build-appveyor.cmd - ..\build-pipelines.cmd = ..\build-pipelines.cmd ..\build.cmd = ..\build.cmd ..\build\install.ps1 = ..\build\install.ps1 ..\build\package.core.nuspec = ..\build\package.core.nuspec From b322920753fcdf003016b781ab52fd4a2f4b062c Mon Sep 17 00:00:00 2001 From: Dan White Date: Fri, 26 Jul 2019 09:09:46 -0700 Subject: [PATCH 07/11] Use confirm dialog before removing doctype --- .../Web/UI/App_Plugins/InnerContent/js/innercontent.js | 10 ++++++++++ .../InnerContent/views/innercontent.doctypepicker.html | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js index 1d0c83c..01b3285 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js @@ -15,6 +15,8 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy vm.tooltipMouseLeave = tooltipMouseLeave; vm.getContentType = getContentType; vm.openDocTypePicker = openDocTypePicker; + vm.showPrompt = showPrompt; + vm.hidePrompt = hidePrompt; vm.sortableOptions = { axis: "y", @@ -108,6 +110,14 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy }; }; + function showPrompt(config) { + config.promptIsVisible = true; + }; + + function hidePrompt(config) { + delete config.promptIsVisible; + }; + function setDirty() { if ($scope.propertyForm) { $scope.propertyForm.$setDirty(); diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.doctypepicker.html b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.doctypepicker.html index 561f9cd..b1a4387 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.doctypepicker.html +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.doctypepicker.html @@ -22,7 +22,12 @@
- + + +
From 73bd1d2712bdbf43fdec3b6799a3564dc3b57527 Mon Sep 17 00:00:00 2001 From: Dan White Date: Fri, 26 Jul 2019 09:37:12 -0700 Subject: [PATCH 08/11] Resolve issue with editing existing types --- .../Web/UI/App_Plugins/InnerContent/js/innercontent.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js index 01b3285..91015ab 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js @@ -51,7 +51,7 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy icContentTypeGuid: "", nameTemplate: "" }; - openDocTypePicker(newItem); + openDocTypePicker(newItem, true); setDirty(); }; @@ -93,7 +93,7 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy }); }; - function openDocTypePicker(config) { + function openDocTypePicker(config, isNew) { vm.docTypePicker = { view: "itempicker", availableItems: vm.docTypes, @@ -101,7 +101,9 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy show: true, submit: function (model) { config.icContentTypeGuid = model.selectedItem.guid; - $scope.model.value.push(config); + if (isNew === true) { + $scope.model.value.push(config); + } updateSelectedDocTypes(); vm.docTypePicker.show = false; From 3421829a0895fc3ca1e3af2bc128cb1440d63a02 Mon Sep 17 00:00:00 2001 From: Dan White Date: Fri, 26 Jul 2019 11:55:53 -0700 Subject: [PATCH 09/11] Refactor to avoid multiple calls to vm.getContentType in view --- .../InnerContent/js/innercontent.js | 62 +++++++++++++++---- .../views/innercontent.doctypepicker.html | 20 +++--- 2 files changed, 60 insertions(+), 22 deletions(-) diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js index 91015ab..1837c08 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js @@ -9,6 +9,7 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy var vm = this; vm.docTypes = []; vm.selectedDocTypes = []; + vm.selectedItems = []; vm.add = add; vm.remove = remove; vm.tooltipMouseOver = tooltipMouseOver; @@ -39,7 +40,14 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy innerContentService.getAllContentTypes().then(function (docTypes) { vm.docTypes = docTypes; + initSelectedItems(); updateSelectedDocTypes(); + + $scope.$watch('vm.selectedItems', _.debounce(function (newVal, oldVal) { + if (newVal !== oldVal) { + updateModel(); + } + }, 300), true); }); if (!$scope.model.value) { @@ -48,15 +56,18 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy function add() { var newItem = { - icContentTypeGuid: "", - nameTemplate: "" + guid: "", + nameTemplate: "", + icon: "", + name: "", + alias: "" }; openDocTypePicker(newItem, true); setDirty(); }; function remove(index) { - $scope.model.value.splice(index, 1); + vm.selectedItems.splice(index, 1); updateSelectedDocTypes(); setDirty(); }; @@ -77,32 +88,59 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy }; }; + function initSelectedItems() { + vm.selectedItems = _.map($scope.model.value, function (i) { + var docType = getContentType(i.icContentTypeGuid); + + return { + guid: i.icContentTypeGuid, + nameTemplate: i.nameTemplate, + icon: docType.icon, + name: docType.name, + alias: docType.alias + }; + }); + } + function updateSelectedDocTypes() { vm.selectedDocTypes = _.filter(vm.docTypes, function (i) { - var match = _.find($scope.model.value, function (c) { - return c.icContentTypeGuid === i.guid; + var match = _.find(vm.selectedItems, function (c) { + return c.guid === i.guid; }); return match !== undefined; }); }; + function updateModel() { + $scope.model.value = _.map(vm.selectedItems, function (i) { + return { + icContentTypeGuid: i.guid, + nameTemplate: i.nameTemplate + }; + }); + } + function getContentType(guid) { return _.find(vm.docTypes, function (d) { return d.guid === guid; }); }; - function openDocTypePicker(config, isNew) { + function openDocTypePicker(item, isNew) { vm.docTypePicker = { view: "itempicker", availableItems: vm.docTypes, selectedItems: vm.selectedDocTypes, show: true, submit: function (model) { - config.icContentTypeGuid = model.selectedItem.guid; + item.guid = model.selectedItem.guid; + item.icon = model.selectedItem.icon; + item.name = model.selectedItem.name; + item.alias = model.selectedItem.alias; + if (isNew === true) { - $scope.model.value.push(config); + vm.selectedItems.push(item); } updateSelectedDocTypes(); @@ -112,12 +150,12 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy }; }; - function showPrompt(config) { - config.promptIsVisible = true; + function showPrompt(item) { + item.promptIsVisible = true; }; - function hidePrompt(config) { - delete config.promptIsVisible; + function hidePrompt(item) { + delete item.promptIsVisible; }; function setDirty() { diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.doctypepicker.html b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.doctypepicker.html index b1a4387..6f8409b 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.doctypepicker.html +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.doctypepicker.html @@ -5,28 +5,28 @@ ng-mouseover="vm.tooltipMouseOver($event)" ng-mouseleave="vm.tooltipMouseLeave()">
-
-
+
+
- {{ vm.getContentType(config.icContentTypeGuid).name || 'Name' }} - ({{ vm.getContentType(config.icContentTypeGuid).alias || 'alias' }}) + {{ item.name || 'Name' }} + ({{ item.alias || 'alias' }})
- +
- - + + on-cancel="vm.hidePrompt(item)">
From 2909aa08347cae0f4746ebe8c5db73b4394ff121 Mon Sep 17 00:00:00 2001 From: Dan White Date: Tue, 30 Jul 2019 12:10:31 -0700 Subject: [PATCH 10/11] Implement content type groups feature --- .../InnerContent/css/innercontent.css | 42 ++++ .../InnerContent/js/innercontent.js | 201 ++++++++++++++---- .../views/innercontent.create.html | 33 +-- .../views/innercontent.doctypepicker.html | 61 ++++-- 4 files changed, 257 insertions(+), 80 deletions(-) diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/css/innercontent.css b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/css/innercontent.css index 7a02751..e200977 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/css/innercontent.css +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/css/innercontent.css @@ -1,5 +1,9 @@ /* Inner Content - Doc Type Picker */ +.inner-content__doctypepicker .list-view-layout__sort-handle { + color: #807c83 +} + .inner-content__doctypepicker .inner-content__help-container { text-align: right; margin-bottom: .5em; @@ -18,6 +22,35 @@ width: 100%; } +/* Inner Content - Doc Type Picker Groups */ + +.inner-content__doctypepicker .inner-content__groups { +} + +.inner-content__doctypepicker .inner-content__group { + margin-bottom: 30px; + border: 1px solid #d8d7d9; +} + + .inner-content__doctypepicker .inner-content__group .list-view-add-layout { + margin: 10px 15px; + } + +.inner-content__doctypepicker .inner-content__group-config { + display: flex; + padding: 10px 15px; + align-items: center; + background-color: #d8d7d9; +} + +.inner-content__doctypepicker .inner-content__group-name { + flex-grow: 1; +} + +.inner-content__doctypepicker .inner-content__group-doctypes { +} + + /* Inner Content - Content Overlay Panel */ .inner-content-overlay > .umb-overlay-right > .umb-overlay__form > .umb-overlay-container { @@ -32,3 +65,12 @@ .inner-content-pane { margin: 30px 20px; } + + .inner-content-pane .inner-content-pane__group { + text-transform: uppercase; + font-size: 12px; + border-bottom: 1px solid #f3f3f5; + padding-bottom: 5px; + margin-top: 20px; + font-weight: bold; + } diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js index 1837c08..5cf28b0 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js @@ -9,9 +9,11 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy var vm = this; vm.docTypes = []; vm.selectedDocTypes = []; - vm.selectedItems = []; - vm.add = add; - vm.remove = remove; + vm.docTypeGroups = []; + vm.addDocType = addDocType; + vm.removeDocType = removeDocType; + vm.addGroup = addGroup; + vm.removeGroup = removeGroup; vm.tooltipMouseOver = tooltipMouseOver; vm.tooltipMouseLeave = tooltipMouseLeave; vm.getContentType = getContentType; @@ -40,21 +42,68 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy innerContentService.getAllContentTypes().then(function (docTypes) { vm.docTypes = docTypes; - initSelectedItems(); + init(); updateSelectedDocTypes(); - $scope.$watch('vm.selectedItems', _.debounce(function (newVal, oldVal) { + $scope.$watch('vm.docTypeGroups', _.debounce(function (newVal, oldVal) { if (newVal !== oldVal) { updateModel(); } }, 300), true); }); - if (!$scope.model.value) { - $scope.model.value = []; + function init() { + if ($scope.model.value && $scope.model.value.length !== 0) { + ensureGroupSupport(); // for data types that were configured before groups feature + + vm.docTypeGroups = _.map($scope.model.value, function (i) { + var docTypes = _.map(i.docTypes, function (d) { + var ct = getContentType(d.icContentTypeGuid); + + return { + guid: d.icContentTypeGuid, + nameTemplate: d.nameTemplate, + icon: ct.icon, + name: ct.name, + alias: ct.alias + }; + }); + + return { + groupName: i.groupName, + docTypes: docTypes + }; + }); + } else { + addGroup(); + } } - function add() { + function ensureGroupSupport() { + if ('groupName' in $scope.model.value[0]) { + return; + } + + $scope.model.value = [{ + groupName: '', + docTypes: $scope.model.value + }]; + } + + function addGroup() { + vm.docTypeGroups.push({ + groupName: '', + docTypes: [] + }); + } + + function removeGroup(index) { + vm.docTypeGroups.splice(index, 1); + updateSelectedDocTypes(); + setDirty(); + } + + function addDocType(group) { var newItem = { guid: "", nameTemplate: "", @@ -62,12 +111,12 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy name: "", alias: "" }; - openDocTypePicker(newItem, true); + openDocTypePicker(newItem, group, true); setDirty(); }; - function remove(index) { - vm.selectedItems.splice(index, 1); + function removeDocType(group, index) { + group.docTypes.splice(index, 1); updateSelectedDocTypes(); setDirty(); }; @@ -88,35 +137,31 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy }; }; - function initSelectedItems() { - vm.selectedItems = _.map($scope.model.value, function (i) { - var docType = getContentType(i.icContentTypeGuid); - - return { - guid: i.icContentTypeGuid, - nameTemplate: i.nameTemplate, - icon: docType.icon, - name: docType.name, - alias: docType.alias - }; - }); - } - function updateSelectedDocTypes() { - vm.selectedDocTypes = _.filter(vm.docTypes, function (i) { - var match = _.find(vm.selectedItems, function (c) { - return c.guid === i.guid; + var selectedGuids = _.reduce(vm.docTypeGroups, function (acc, cur) { + _.each(cur.docTypes, function (i) { + acc.push(i.guid); }); + return acc; + }, []); - return match !== undefined; + vm.selectedDocTypes = _.filter(vm.docTypes, function (i) { + return _.contains(selectedGuids, i.guid); }); }; function updateModel() { - $scope.model.value = _.map(vm.selectedItems, function (i) { + $scope.model.value = _.map(vm.docTypeGroups, function (i) { + var docTypes = _.map(i.docTypes, function (d) { + return { + icContentTypeGuid: d.guid, + nameTemplate: d.nameTemplate + }; + }); + return { - icContentTypeGuid: i.guid, - nameTemplate: i.nameTemplate + groupName: i.groupName, + docTypes: docTypes }; }); } @@ -127,7 +172,7 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy }); }; - function openDocTypePicker(item, isNew) { + function openDocTypePicker(item, group, isNew) { vm.docTypePicker = { view: "itempicker", availableItems: vm.docTypes, @@ -140,7 +185,7 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy item.alias = model.selectedItem.alias; if (isNew === true) { - vm.selectedItems.push(item); + group.docTypes.push(item); } updateSelectedDocTypes(); @@ -179,8 +224,10 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.Inner $scope.allowBlank = blueprintConfig.allowBlank; $scope.enableFilter = $scope.model.enableFilter; - if ($scope.allowedTypes.length === 1) { - $scope.selectedDocType = $scope.allowedTypes[0]; + var allowedTypes = getAllowedTypes(); + + if (allowedTypes.length === 1) { + $scope.selectedDocType = allowedTypes[0]; $scope.selectContentType = false; $scope.selectBlueprint = true; } else { @@ -189,6 +236,19 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.Inner } }; + function getAllowedTypes() { + if ('groupName' in $scope.allowedTypes[0]) { + var flattenedAllowedTypes = _.reduce($scope.allowedTypes, function (acc, cur) { + acc = acc.concat(cur.docTypes); + return acc; + }, []); + + return flattenedAllowedTypes; + } else { + return $scope.allowedTypes; + } + } + function createBlank(docTypeKey) { $scope.model.selectedItem = { "key": docTypeKey, "blueprint": null }; $scope.model.submit($scope.model); @@ -256,7 +316,9 @@ angular.module("umbraco.directives").directive("innerContentOverlay", [ scope.overlayClasses = scope.overlayClasses || []; var getContentType = function (guid) { - return _.find(scope.config.contentTypes, function (ct) { + var contentTypes = getFlattenedContentTypes(scope.config.contentTypes); + + return _.find(contentTypes, function (ct) { return ct.icContentTypeGuid.toLowerCase() === guid.toLowerCase(); }); }; @@ -286,6 +348,17 @@ angular.module("umbraco.directives").directive("innerContentOverlay", [ }; + var getFlattenedContentTypes = function (contentTypes) { + if ('groupName' in contentTypes[0]) { + return _.reduce(contentTypes, function (acc, cur) { + acc = acc.concat(cur.docTypes); + return acc; + }, []); + } else { + return contentTypes; + } + }; + scope.contentTypePickerOverlay = { view: Umbraco.Sys.ServerVariables.umbracoSettings.appPluginsPath + "/innercontent/views/innercontent.create.html", title: "Insert Content", @@ -328,13 +401,15 @@ angular.module("umbraco.directives").directive("innerContentOverlay", [ scope.openContentTypePickerOverlay = function () { - if (scope.contentTypePickerOverlay.availableItems.length === 0) { + var availableItems = getFlattenedContentTypes(scope.contentTypePickerOverlay.availableItems); + + if (availableItems.length === 0) { scope.closeAllOverlays(); return; } - if (scope.contentTypePickerOverlay.availableItems.length === 1 && _.isEmpty(scope.contentTypePickerOverlay.availableItems[0].blueprints)) { - var ct = getContentType(scope.contentTypePickerOverlay.availableItems[0].key); + if (availableItems.length === 1 && _.isEmpty(availableItems[0].blueprints)) { + var ct = getContentType(availableItems[0].key); createEditorModel(ct).then(function (em) { scope.currentItem = em; scope.openContentEditorOverlay(); @@ -387,6 +462,17 @@ angular.module("umbraco.directives").directive("innerContentOverlay", [ } }; + function ensureGroupSupport(contentTypes) { + if ('groupName' in contentTypes[0]) { + return contentTypes; + } + + return [{ + groupName: '', + docTypes: contentTypes + }]; + } + var initOpen = function () { // Map scaffolds to content type picker list @@ -414,13 +500,28 @@ angular.module("umbraco.directives").directive("innerContentOverlay", [ // If overlay items haven't be initialized, then intialize them if (!scope.config.contentTypePickerItems) { - var guids = scope.config.contentTypes.map(function (itm) { + var flattenedContentTypes = getFlattenedContentTypes(scope.config.contentTypes); + var guids = flattenedContentTypes.map(function (itm) { return itm.icContentTypeGuid; }); + innerContentService.getContentTypesByGuid(guids).then(function (contentTypes) { + // get grouped content types using a copy of config.doctypes as a base + var groupedContentTypes = angular.copy(scope.config.contentTypes); + groupedContentTypes = ensureGroupSupport(groupedContentTypes); + + groupedContentTypes = _.map(groupedContentTypes, function (g) { + g.docTypes = _.map(g.docTypes, function (i) { + return _.find(contentTypes, function (c) { + return c.guid === i.icContentTypeGuid; + }); + }); + return g; + }); + // Cache items in the PE's config so we only request these once per PE instance - scope.config.contentTypePickerItems = contentTypes; + scope.config.contentTypePickerItems = groupedContentTypes; initOpen(); @@ -558,7 +659,19 @@ angular.module("umbraco").factory("innerContentService", [ return (test !== Object(test)); }; + var getFlattenedContentTypes = function (contentTypes) { + if ('groupName' in contentTypes[0]) { + return _.reduce(contentTypes, function (acc, cur) { + acc = acc.concat(cur.docTypes); + return acc; + }, []); + } else { + return contentTypes; + } + }; + self.populateName = function (itm, idx, contentTypes) { + contentTypes = getFlattenedContentTypes(contentTypes); var contentType = _.find(contentTypes, function (itm2) { return itm2.icContentTypeGuid === itm.icContentTypeGuid; @@ -658,7 +771,9 @@ angular.module("umbraco").factory("innerContentService", [ }; self.createDefaultDbModel = function (contentType) { - return self.createEditorModel(contentType).then(function (editorModel) { + var docType = ('groupName' in contentType) ? contentType.docTypes[0] : contentType; + + return self.createEditorModel(docType).then(function (editorModel) { return self.createDbModel(editorModel); }); }; diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.create.html b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.create.html index baf030a..cbfca4b 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.create.html +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/views/innercontent.create.html @@ -1,4 +1,4 @@ -
+
-
-
- -
- - - -
-
- {{ item.name || 'Name' }} - ({{ item.alias || 'alias' }}) -
-
- -
-
+
+
+
+ +
+ +
- - + + on-confirm="vm.removeGroup($index)" + on-cancel="vm.hidePrompt(group)">
+
+
+ +
+ + + +
+
+ {{ item.name || 'Name' }} + ({{ item.alias || 'alias' }}) +
+
+ +
+
+
+ + + +
+
+
+ Add Content Type +
- Add Content Type + Add Group
Date: Tue, 30 Jul 2019 13:31:26 -0700 Subject: [PATCH 11/11] Reorganize functions --- .../InnerContent/js/innercontent.js | 102 +++++++++--------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js index 5cf28b0..430c34e 100644 --- a/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js +++ b/src/Our.Umbraco.InnerContent/Web/UI/App_Plugins/InnerContent/js/innercontent.js @@ -90,53 +90,6 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy }]; } - function addGroup() { - vm.docTypeGroups.push({ - groupName: '', - docTypes: [] - }); - } - - function removeGroup(index) { - vm.docTypeGroups.splice(index, 1); - updateSelectedDocTypes(); - setDirty(); - } - - function addDocType(group) { - var newItem = { - guid: "", - nameTemplate: "", - icon: "", - name: "", - alias: "" - }; - openDocTypePicker(newItem, group, true); - setDirty(); - }; - - function removeDocType(group, index) { - group.docTypes.splice(index, 1); - updateSelectedDocTypes(); - setDirty(); - }; - - function tooltipMouseOver($event) { - vm.tooltip = { - show: true, - event: $event, - content: $event.currentTarget.dataset.tooltip - }; - }; - - function tooltipMouseLeave() { - vm.tooltip = { - show: false, - event: null, - content: null - }; - }; - function updateSelectedDocTypes() { var selectedGuids = _.reduce(vm.docTypeGroups, function (acc, cur) { _.each(cur.docTypes, function (i) { @@ -164,14 +117,39 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy docTypes: docTypes }; }); - } + }; - function getContentType(guid) { - return _.find(vm.docTypes, function (d) { - return d.guid === guid; + function addGroup() { + vm.docTypeGroups.push({ + groupName: '', + docTypes: [] }); }; + function removeGroup(index) { + vm.docTypeGroups.splice(index, 1); + updateSelectedDocTypes(); + setDirty(); + }; + + function addDocType(group) { + var newItem = { + guid: "", + nameTemplate: "", + icon: "", + name: "", + alias: "" + }; + openDocTypePicker(newItem, group, true); + setDirty(); + }; + + function removeDocType(group, index) { + group.docTypes.splice(index, 1); + updateSelectedDocTypes(); + setDirty(); + }; + function openDocTypePicker(item, group, isNew) { vm.docTypePicker = { view: "itempicker", @@ -195,6 +173,22 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy }; }; + function tooltipMouseOver($event) { + vm.tooltip = { + show: true, + event: $event, + content: $event.currentTarget.dataset.tooltip + }; + }; + + function tooltipMouseLeave() { + vm.tooltip = { + show: false, + event: null, + content: null + }; + }; + function showPrompt(item) { item.promptIsVisible = true; }; @@ -203,6 +197,12 @@ angular.module("umbraco").controller("Our.Umbraco.InnerContent.Controllers.DocTy delete item.promptIsVisible; }; + function getContentType(guid) { + return _.find(vm.docTypes, function (d) { + return d.guid === guid; + }); + }; + function setDirty() { if ($scope.propertyForm) { $scope.propertyForm.$setDirty();