From 426aa981f8d8758fd567c332e95325a21dbcb0e6 Mon Sep 17 00:00:00 2001 From: Bjarne Fyrstenborg Date: Tue, 15 Oct 2019 18:13:18 +0200 Subject: [PATCH] Pick macro parameters in an infinite editor like content type properties (#6586) --- .../src/common/resources/macro.resource.js | 14 ++ .../datatypepicker.controller.js | 28 ++-- .../datatypepicker/datatypepicker.html | 97 +++++++------ .../macroparameterpicker.controller.js | 127 ++++++++++++++++++ .../macroparameterpicker.html | 106 +++++++++++++++ .../macropicker/macropicker.controller.js | 2 - .../macropicker/macropicker.html | 4 +- .../infiniteeditors/parameter.controller.js | 32 ++++- .../macros/infiniteeditors/parameter.html | 61 ++++++--- .../views/macros/macros.edit.controller.js | 17 --- .../views/macro.parameters.controller.js | 57 +++++--- .../src/views/macros/views/parameters.html | 55 ++++---- .../src/views/macros/views/settings.html | 2 +- src/Umbraco.Web/Editors/MacrosController.cs | 33 +++++ 14 files changed, 500 insertions(+), 135 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macroparameterpicker/macroparameterpicker.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macroparameterpicker/macroparameterpicker.html diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/macro.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/macro.resource.js index 73a1651b5e..c9ce7866e5 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/macro.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/macro.resource.js @@ -105,6 +105,20 @@ function macroResource($q, $http, umbRequestHelper) { ); }, + getGroupedParameterEditors: function () { + return umbRequestHelper.resourcePromise( + $http.get(umbRequestHelper.getApiUrl("macroApiBaseUrl", "GetGroupedParameterEditors"), + "Failed to get parameter editors") + ); + }, + + getParameterEditorByAlias: function(alias) { + return umbRequestHelper.resourcePromise( + $http.get(umbRequestHelper.getApiUrl("macroApiBaseUrl", "GetParameterEditorByAlias", { "alias": alias }), + "Failed to get parameter editor") + ); + }, + getById: function(id) { return umbRequestHelper.resourcePromise( $http.get(umbRequestHelper.getApiUrl("macroApiBaseUrl", "GetById", { "id": id }), "Failed to get macro") diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypepicker/datatypepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypepicker/datatypepicker.controller.js index c86f55b255..167e74c25d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypepicker/datatypepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypepicker/datatypepicker.controller.js @@ -10,7 +10,7 @@ (function() { "use strict"; - function DataTypePicker($scope, $filter, dataTypeResource, dataTypeHelper, contentTypeResource, localizationService, editorService) { + function DataTypePicker($scope, $filter, dataTypeResource, contentTypeResource, localizationService, editorService) { var vm = this; @@ -122,10 +122,18 @@ vm.showTabs = false; var regex = new RegExp(vm.searchTerm, "i"); + + var userConfigured = filterCollection(vm.userConfigured, regex), + typesAndEditors = filterCollection(vm.typesAndEditors, regex); + + var totalResults = _.reduce(_.pluck(_.union(userConfigured, typesAndEditors), 'count'), (m, n) => m + n, 0); + vm.filterResult = { - userConfigured: filterCollection(vm.userConfigured, regex), - typesAndEditors: filterCollection(vm.typesAndEditors, regex) + userConfigured: userConfigured, + typesAndEditors: typesAndEditors, + totalResults: totalResults }; + } else { vm.filterResult = null; vm.showTabs = true; @@ -134,11 +142,15 @@ function filterCollection(collection, regex) { return _.map(_.keys(collection), function (key) { + + var filteredDataTypes = $filter('filter')(collection[key], function (dataType) { + return regex.test(dataType.name) || regex.test(dataType.alias); + }); + return { group: key, - dataTypes: $filter('filter')(collection[key], function (dataType) { - return regex.test(dataType.name) || regex.test(dataType.alias); - }) + count: filteredDataTypes.length, + dataTypes: filteredDataTypes } }); } @@ -150,7 +162,6 @@ propertyDetails.title = property.name; $scope.model.itemDetails = propertyDetails; - } function hideDetailsOverlay() { @@ -177,7 +188,6 @@ }; editorService.open(dataTypeSettings); - } function pickDataType(selectedDataType) { @@ -205,7 +215,7 @@ } function close() { - if($scope.model.close) { + if ($scope.model.close) { $scope.model.close(); } } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypepicker/datatypepicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypepicker/datatypepicker.html index fd859b9e2e..b99cd1ceef 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypepicker/datatypepicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypepicker/datatypepicker.html @@ -20,17 +20,19 @@ + +
+
-
-
-
-
{{result.group}}
- +
+
+
+
+
{{result.group}}
+ +
-
-
-
-
{{result.group}}
- +
+
+
+
+
{{result.group}}
+ +
+ + + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macroparameterpicker/macroparameterpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macroparameterpicker/macroparameterpicker.controller.js new file mode 100644 index 0000000000..5b81cb947d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macroparameterpicker/macroparameterpicker.controller.js @@ -0,0 +1,127 @@ +/** + * @ngdoc controller + * @name Umbraco.Editors.MacroParameterPickerController + * @function + * + * @description + * The controller for the content type editor macro parameter dialog + */ + +(function() { + "use strict"; + + function MacroParameterController($scope, $filter, macroResource, localizationService, editorService) { + + var vm = this; + + vm.searchTerm = ""; + vm.parameterEditors = []; + vm.loading = false; + vm.labels = {}; + + vm.filterItems = filterItems; + vm.showDetailsOverlay = showDetailsOverlay; + vm.hideDetailsOverlay = hideDetailsOverlay; + vm.pickParameterEditor = pickParameterEditor; + vm.close = close; + + function init() { + setTitle(); + getGroupedParameterEditors(); + } + + function setTitle() { + if (!$scope.model.title) { + localizationService.localize("defaultdialogs_selectEditor") + .then(function(data){ + $scope.model.title = data; + }); + } + } + + function getGroupedParameterEditors() { + + vm.loading = true; + + macroResource.getGroupedParameterEditors().then(function (data) { + vm.parameterEditors = data; + vm.loading = false; + }, function () { + vm.loading = false; + }); + + } + + function filterItems() { + // clear item details + $scope.model.itemDetails = null; + + if (vm.searchTerm) { + + var regex = new RegExp(vm.searchTerm, "i"); + + var parameterEditors = filterCollection(vm.parameterEditors, regex); + + var totalResults = _.reduce(_.pluck(parameterEditors, 'count'), (m, n) => m + n, 0); + + vm.filterResult = { + parameterEditors: parameterEditors, + totalResults: totalResults + }; + } else { + vm.filterResult = null; + } + } + + function filterCollection(collection, regex) { + return _.map(_.keys(collection), function (key) { + + var filteredEditors = $filter('filter')(collection[key], function (editor) { + return regex.test(editor.name) || regex.test(editor.alias); + }); + + return { + group: key, + count: filteredEditors.length, + parameterEditors: filteredEditors + } + }); + } + + function showDetailsOverlay(property) { + + var propertyDetails = {}; + propertyDetails.icon = property.icon; + propertyDetails.title = property.name; + + $scope.model.itemDetails = propertyDetails; + } + + function hideDetailsOverlay() { + $scope.model.itemDetails = null; + } + + function pickParameterEditor(selectedParameterEditor) { + + console.log("pickParameterEditor", selectedParameterEditor); + console.log("$scope.model", $scope.model); + + $scope.model.parameter.editor = selectedParameterEditor.alias; + $scope.model.parameter.dataTypeName = selectedParameterEditor.name; + $scope.model.parameter.dataTypeIcon = selectedParameterEditor.icon; + + $scope.model.submit($scope.model); + } + + function close() { + if ($scope.model.close) { + $scope.model.close(); + } + } + + init(); + } + + angular.module("umbraco").controller("Umbraco.Editors.MacroParameterPickerController", MacroParameterController); + +})(); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macroparameterpicker/macroparameterpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macroparameterpicker/macroparameterpicker.html new file mode 100644 index 0000000000..9f2b56401d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macroparameterpicker/macroparameterpicker.html @@ -0,0 +1,106 @@ +
+ + + +
+ + + + + + + + + +
+ +
+ + + +
+ +
+ + +
+
+
+
+
{{result.group}}
+ +
+
+
+ + + + +
+ +
+
+
+ + + + + + + + +
+ +
+ +
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macropicker/macropicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macropicker/macropicker.controller.js index aa63f2d6d6..dfc77f786c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macropicker/macropicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macropicker/macropicker.controller.js @@ -41,8 +41,6 @@ function MacroPickerController($scope, entityResource, macroResource, umbPropEdi macroResource.getMacroParameters($scope.model.selectedMacro.id) .then(function (data) { - - //go to next page if there are params otherwise we can just exit if (!angular.isArray(data) || data.length === 0) { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macropicker/macropicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macropicker/macropicker.html index 66c64657a9..fc1bec4ec1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macropicker/macropicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/macropicker/macropicker.html @@ -32,10 +32,10 @@
  • - + - {{ availableItem.name }} + {{availableItem.name}}
  • diff --git a/src/Umbraco.Web.UI.Client/src/views/macros/infiniteeditors/parameter.controller.js b/src/Umbraco.Web.UI.Client/src/views/macros/infiniteeditors/parameter.controller.js index 7dddbb42d1..7d4df17277 100644 --- a/src/Umbraco.Web.UI.Client/src/views/macros/infiniteeditors/parameter.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/macros/infiniteeditors/parameter.controller.js @@ -1,14 +1,43 @@ (function() { "use strict"; - function ParameterEditorController($scope, formHelper) { + function ParameterEditorController($scope, formHelper, editorService) { const vm = this; vm.submit = submit; vm.close = close; + vm.openMacroParameterPicker = openMacroParameterPicker; + + function openMacroParameterPicker(parameter) { + + vm.focusOnMandatoryField = false; + + var overlay = { + parameter: $scope.model.parameter, + view: "views/common/infiniteeditors/macroparameterpicker/macroparameterpicker.html", + size: "small", + submit: function (model) { + + vm.focusOnMandatoryField = true; + + // update property + parameter.editor = model.parameter.editor; + + editorService.close(); + }, + close: function (model) { + editorService.close(); + } + }; + + editorService.open(overlay); + } + function submit() { + console.log("model", $scope.model); + if ($scope.model && $scope.model.submit && formHelper.submitForm({scope: $scope})) { $scope.model.submit($scope.model); } @@ -19,7 +48,6 @@ $scope.model.close(); } } - } angular.module("umbraco").controller("Umbraco.Editors.ParameterEditorController", ParameterEditorController); diff --git a/src/Umbraco.Web.UI.Client/src/views/macros/infiniteeditors/parameter.html b/src/Umbraco.Web.UI.Client/src/views/macros/infiniteeditors/parameter.html index ae46bf6057..c1f83cd0b7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/macros/infiniteeditors/parameter.html +++ b/src/Umbraco.Web.UI.Client/src/views/macros/infiniteeditors/parameter.html @@ -1,34 +1,62 @@ 
    -
    + - + - + - - - +
    +
    + +
    + Required label +
    +
    +
    + +
    +
    - - - + + + - - - +
    @@ -40,6 +68,7 @@ { + openOverlay({}, vm.labels.addParameter, (newParameter) => { if (!$scope.model.macro.parameters) { $scope.model.macro.parameters = []; } @@ -40,23 +48,43 @@ function MacrosParametersController($scope, editorService, localizationService) }); } - $scope.edit = function (parameter, evt) { + function edit(parameter, evt) { evt.preventDefault(); - openOverlay(parameter, $scope.labels.editParameter, (newParameter) => { - parameter.key = newParameter.key; - parameter.label = newParameter.label; - parameter.editor = newParameter.editor; - setDirty(); + var promises = [ + getParameterEditorByAlias(parameter.editor) + ]; + + $q.all(promises).then(function (values) { + parameter.dataTypeName = values[0].name; + + openOverlay(parameter, vm.labels.editParameter, (newParameter) => { + + parameter.key = newParameter.key; + parameter.label = newParameter.label; + parameter.editor = newParameter.editor; + setDirty(); + }); }); } + function getParameterEditorByAlias(alias) { + var deferred = $q.defer(); + + macroResource.getParameterEditorByAlias(alias).then(function (data) { + deferred.resolve(data); + }, function () { + deferred.reject(); + }); + + return deferred.promise; + } + function openOverlay(parameter, title, onSubmit) { const ruleDialog = { title: title, parameter: _.clone(parameter), - editors : $scope.model.parameterEditors, view: "views/macros/infiniteeditors/parameter.html", size: "small", submit: function (model) { @@ -69,7 +97,6 @@ function MacrosParametersController($scope, editorService, localizationService) }; editorService.open(ruleDialog); - } function setDirty() { @@ -78,10 +105,8 @@ function MacrosParametersController($scope, editorService, localizationService) function init() { localizationService.localizeMany(["macro_addParameter", "macro_editParameter"]).then(function (data) { - $scope.labels = { - addParameter: data[0], - editParameter: data[1] - } + vm.labels.addParameter = data[0]; + vm.labels.editParameter = data[1]; }); } diff --git a/src/Umbraco.Web.UI.Client/src/views/macros/views/parameters.html b/src/Umbraco.Web.UI.Client/src/views/macros/views/parameters.html index 0aa4a47fc0..6ea79fe16d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/macros/views/parameters.html +++ b/src/Umbraco.Web.UI.Client/src/views/macros/views/parameters.html @@ -1,33 +1,34 @@ - - -
    -
    -
    Parameters
    - Define the parameters that should be available when using this macro. -
    -
    -
    -
    -
    - -
    - {{parameter.label}} ({{parameter.key}}){{parameter.editor}} -
    -
    - Edit - Remove +
    + + +
    +
    +
    Parameters
    + Define the parameters that should be available when using this macro. +
    +
    +
    +
    +
    + +
    + {{parameter.label}} ({{parameter.key}}){{parameter.editor}} +
    +
    + Edit + Remove +
    + +
    - -
    -
    - - + + +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/macros/views/settings.html b/src/Umbraco.Web.UI.Client/src/views/macros/views/settings.html index 60aeae0d92..d34cf1810d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/macros/views/settings.html +++ b/src/Umbraco.Web.UI.Client/src/views/macros/views/settings.html @@ -1,4 +1,4 @@ -
    +
    diff --git a/src/Umbraco.Web/Editors/MacrosController.cs b/src/Umbraco.Web/Editors/MacrosController.cs index 429e8b6190..3cb161e547 100644 --- a/src/Umbraco.Web/Editors/MacrosController.cs +++ b/src/Umbraco.Web/Editors/MacrosController.cs @@ -229,6 +229,39 @@ namespace Umbraco.Web.Editors return this.Request.CreateResponse(HttpStatusCode.OK, Current.ParameterEditors); } + /// + /// Gets the available parameter editors grouped by their group. + /// + /// + /// The . + /// + public HttpResponseMessage GetGroupedParameterEditors() + { + var parameterEditors = Current.ParameterEditors.ToArray(); + + var grouped = parameterEditors + .GroupBy(x => x.Group.IsNullOrWhiteSpace() ? "" : x.Group.ToLower()) + .OrderBy(x => x.Key) + .ToDictionary(group => group.Key, group => group.OrderBy(d => d.Name).AsEnumerable()); + + return this.Request.CreateResponse(HttpStatusCode.OK, grouped); + } + + /// + /// Get parameter editor by alias. + /// + /// + /// The . + /// + public HttpResponseMessage GetParameterEditorByAlias(string alias) + { + var parameterEditors = Current.ParameterEditors.ToArray(); + + var parameterEditor = parameterEditors.FirstOrDefault(x => x.Alias.InvariantEquals(alias)); + + return this.Request.CreateResponse(HttpStatusCode.OK, parameterEditor); + } + /// /// Returns a error response and optionally logs it ///