From 67db2e0724b955b7a6f0183f20b1e79f630f53b6 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Thu, 7 Jan 2021 09:52:57 -0500 Subject: [PATCH] Afform - Refactor afGuiEntity to a component --- ext/afform/admin/ang/afGuiEditor.js | 348 +++++++++--------- ext/afform/admin/ang/afGuiEditor/canvas.html | 2 +- ext/afform/admin/ang/afGuiEditor/entity.html | 18 +- .../ang/afGuiEditor/entityConfig/Contact.html | 2 +- .../ang/afGuiEditor/entityConfig/Generic.html | 2 +- ext/afform/admin/ang/afGuiEditor/main.html | 4 - ext/afform/admin/ang/afGuiEditor/palette.html | 4 +- 7 files changed, 186 insertions(+), 194 deletions(-) diff --git a/ext/afform/admin/ang/afGuiEditor.js b/ext/afform/admin/ang/afGuiEditor.js index 00373d0376..6b1c2c0f79 100644 --- a/ext/afform/admin/ang/afGuiEditor.js +++ b/ext/afform/admin/ang/afGuiEditor.js @@ -14,7 +14,6 @@ $scope.saving = false; $scope.selectedEntityName = null; $scope.meta = this.meta = CRM.afGuiEditor; - this.scope = $scope; var editor = this; var newForm = { title: '', @@ -65,12 +64,12 @@ } $scope.canvasTab = 'layout'; $scope.layoutHtml = ''; - $scope.layout = findRecursive($scope.afform.layout, {'#tag': 'af-form'})[0]; - $scope.entities = findRecursive($scope.layout['#children'], {'#tag': 'af-entity'}, 'name'); + editor.layout = findRecursive($scope.afform.layout, {'#tag': 'af-form'})[0]; + $scope.entities = findRecursive(editor.layout['#children'], {'#tag': 'af-entity'}, 'name'); if (editor.name == '0') { editor.addEntity('Individual'); - $scope.layout['#children'].push($scope.meta.elements.submit.element); + editor.layout['#children'].push($scope.meta.elements.submit.element); } // Set changesSaved to true on initial load, false thereafter whenever changes are made to the model @@ -82,7 +81,7 @@ $scope.updateLayoutHtml = function() { $scope.layoutHtml = '...Loading...'; - crmApi4('Afform', 'convert', {layout: [$scope.layout], from: 'deep', to: 'html', formatWhitespace: true}) + crmApi4('Afform', 'convert', {layout: [editor.layout], from: 'deep', to: 'html', formatWhitespace: true}) .then(function(r){ $scope.layoutHtml = r[0].layout || '(Error)'; }) @@ -105,8 +104,8 @@ label: meta.label + ' ' + num }); // Add this af-entity tag after the last existing one - var pos = 1 + _.findLastIndex($scope.layout['#children'], {'#tag': 'af-entity'}); - $scope.layout['#children'].splice(pos, 0, $scope.entities[type + num]); + var pos = 1 + _.findLastIndex(editor.layout['#children'], {'#tag': 'af-entity'}); + editor.layout['#children'].splice(pos, 0, $scope.entities[type + num]); // Create a new af-fieldset container for the entity var fieldset = _.cloneDeep(editor.meta.elements.fieldset.element); fieldset['af-fieldset'] = type + num; @@ -116,19 +115,19 @@ fieldset['#children'].push({'#tag': 'afblock-name-' + type.toLowerCase()}); } // Attempt to place the new af-fieldset after the last one on the form - pos = 1 + _.findLastIndex($scope.layout['#children'], 'af-fieldset'); + pos = 1 + _.findLastIndex(editor.layout['#children'], 'af-fieldset'); if (pos) { - $scope.layout['#children'].splice(pos, 0, fieldset); + editor.layout['#children'].splice(pos, 0, fieldset); } else { - $scope.layout['#children'].push(fieldset); + editor.layout['#children'].push(fieldset); } return type + num; }; this.removeEntity = function(entityName) { delete $scope.entities[entityName]; - removeRecursive($scope.layout['#children'], {'#tag': 'af-entity', name: entityName}); - removeRecursive($scope.layout['#children'], {'af-fieldset': entityName}); + removeRecursive(editor.layout['#children'], {'#tag': 'af-entity', name: entityName}); + removeRecursive(editor.layout['#children'], {'af-fieldset': entityName}); this.selectEntity(null); }; @@ -248,197 +247,192 @@ return str ? _.unique(_.trim(str).split(/\s+/g)) : []; } - angular.module('afGuiEditor').directive('afGuiEntity', function($timeout) { - return { - restrict: 'A', - templateUrl: '~/afGuiEditor/entity.html', - scope: { - entity: '=afGuiEntity' - }, - require: '^^afGuiEditor', - link: function ($scope, element, attrs, editor) { - $scope.editor = editor; - }, - controller: function ($scope) { - var ts = $scope.ts = CRM.ts(); - $scope.controls = {}; - $scope.fieldList = []; - $scope.blockList = []; - $scope.blockTitles = []; - $scope.elementList = []; - $scope.elementTitles = []; - - function getEntityType() { - return $scope.entity.type === 'Contact' ? $scope.entity.data.contact_type : $scope.entity.type; - } + angular.module('afGuiEditor').component('afGuiEntity', { + templateUrl: '~/afGuiEditor/entity.html', + bindings: { + entity: '<' + }, + require: {editor: '^^afGuiEditor'}, + controller: function ($scope, $timeout) { + var ts = $scope.ts = CRM.ts(); + var ctrl = this; + $scope.controls = {}; + $scope.fieldList = []; + $scope.blockList = []; + $scope.blockTitles = []; + $scope.elementList = []; + $scope.elementTitles = []; + + function getEntityType() { + return ctrl.entity.type === 'Contact' ? ctrl.entity.data.contact_type : ctrl.entity.type; + } - $scope.getMeta = function() { - return $scope.editor ? $scope.editor.meta.entities[getEntityType()] : {}; - }; + $scope.getMeta = function() { + return ctrl.editor ? ctrl.editor.meta.entities[getEntityType()] : {}; + }; - $scope.valuesFields = function() { - var fields = _.transform($scope.getMeta().fields, function(fields, field) { - fields.push({id: field.name, text: field.label, disabled: $scope.fieldInUse(field.name)}); - }, []); - return {results: fields}; - }; + $scope.valuesFields = function() { + var fields = _.transform($scope.getMeta().fields, function(fields, field) { + fields.push({id: field.name, text: field.label, disabled: $scope.fieldInUse(field.name)}); + }, []); + return {results: fields}; + }; - $scope.removeValue = function(entity, fieldName) { - delete entity.data[fieldName]; - }; + $scope.removeValue = function(entity, fieldName) { + delete entity.data[fieldName]; + }; - function buildPaletteLists() { - var search = $scope.controls.fieldSearch ? $scope.controls.fieldSearch.toLowerCase() : null; - buildFieldList(search); - buildBlockList(search); - buildElementList(search); - } + function buildPaletteLists() { + var search = $scope.controls.fieldSearch ? $scope.controls.fieldSearch.toLowerCase() : null; + buildFieldList(search); + buildBlockList(search); + buildElementList(search); + } - function buildFieldList(search) { - $scope.fieldList.length = 0; - $scope.fieldList.push({ - entityName: $scope.entity.name, - entityType: getEntityType(), - label: ts('%1 Fields', {1: $scope.getMeta().label}), - fields: filterFields($scope.getMeta().fields) - }); + function buildFieldList(search) { + $scope.fieldList.length = 0; + $scope.fieldList.push({ + entityName: ctrl.entity.name, + entityType: getEntityType(), + label: ts('%1 Fields', {1: $scope.getMeta().label}), + fields: filterFields($scope.getMeta().fields) + }); + + _.each(ctrl.editor.meta.entities, function(entity, entityName) { + if (check(ctrl.editor.layout['#children'], {'af-join': entityName})) { + $scope.fieldList.push({ + entityName: ctrl.entity.name + '-join-' + entityName, + entityType: entityName, + label: ts('%1 Fields', {1: entity.label}), + fields: filterFields(entity.fields) + }); + } + }); - _.each($scope.editor.meta.entities, function(entity, entityName) { - if (check($scope.editor.scope.layout['#children'], {'af-join': entityName})) { - $scope.fieldList.push({ - entityName: $scope.entity.name + '-join-' + entityName, - entityType: entityName, - label: ts('%1 Fields', {1: entity.label}), - fields: filterFields(entity.fields) + function filterFields(fields) { + return _.transform(fields, function(fieldList, field) { + if (!search || _.contains(field.name, search) || _.contains(field.label.toLowerCase(), search)) { + fieldList.push({ + "#tag": "af-field", + name: field.name }); } - }); - - function filterFields(fields) { - return _.transform(fields, function(fieldList, field) { - if (!search || _.contains(field.name, search) || _.contains(field.label.toLowerCase(), search)) { - fieldList.push({ - "#tag": "af-field", - name: field.name - }); - } - }, []); - } + }, []); } + } - function buildBlockList(search) { - $scope.blockList.length = 0; - $scope.blockTitles.length = 0; - _.each($scope.editor.meta.blocks, function(block, directive) { - if ((!search || _.contains(directive, search) || _.contains(block.name.toLowerCase(), search) || _.contains(block.title.toLowerCase(), search)) && - (block.block === '*' || block.block === $scope.entity.type || ($scope.entity.type === 'Contact' && block.block === $scope.entity.data.contact_type)) - ) { - var item = {"#tag": block.join ? "div" : directive}; - if (block.join) { - item['af-join'] = block.join; - item['#children'] = [{"#tag": directive}]; - } - if (block.repeat) { - item['af-repeat'] = ts('Add'); - item.min = '1'; - if (typeof block.repeat === 'number') { - item.max = '' + block.repeat; - } + function buildBlockList(search) { + $scope.blockList.length = 0; + $scope.blockTitles.length = 0; + _.each(ctrl.editor.meta.blocks, function(block, directive) { + if ((!search || _.contains(directive, search) || _.contains(block.name.toLowerCase(), search) || _.contains(block.title.toLowerCase(), search)) && + (block.block === '*' || block.block === ctrl.entity.type || (ctrl.entity.type === 'Contact' && block.block === ctrl.entity.data.contact_type)) + ) { + var item = {"#tag": block.join ? "div" : directive}; + if (block.join) { + item['af-join'] = block.join; + item['#children'] = [{"#tag": directive}]; + } + if (block.repeat) { + item['af-repeat'] = ts('Add'); + item.min = '1'; + if (typeof block.repeat === 'number') { + item.max = '' + block.repeat; } - $scope.blockList.push(item); - $scope.blockTitles.push(block.title); } - }); - } + $scope.blockList.push(item); + $scope.blockTitles.push(block.title); + } + }); + } - function buildElementList(search) { - $scope.elementList.length = 0; - $scope.elementTitles.length = 0; - _.each($scope.editor.meta.elements, function(element, name) { - if (!search || _.contains(name, search) || _.contains(element.title.toLowerCase(), search)) { - var node = _.cloneDeep(element.element); - if (name === 'fieldset') { - node['af-fieldset'] = $scope.entity.name; - } - $scope.elementList.push(node); - $scope.elementTitles.push(name === 'fieldset' ? ts('Fieldset for %1', {1: $scope.entity.label}) : element.title); + function buildElementList(search) { + $scope.elementList.length = 0; + $scope.elementTitles.length = 0; + _.each(ctrl.editor.meta.elements, function(element, name) { + if (!search || _.contains(name, search) || _.contains(element.title.toLowerCase(), search)) { + var node = _.cloneDeep(element.element); + if (name === 'fieldset') { + node['af-fieldset'] = ctrl.entity.name; } - }); - } + $scope.elementList.push(node); + $scope.elementTitles.push(name === 'fieldset' ? ts('Fieldset for %1', {1: ctrl.entity.label}) : element.title); + } + }); + } - $scope.clearSearch = function() { - $scope.controls.fieldSearch = ''; - }; + $scope.clearSearch = function() { + $scope.controls.fieldSearch = ''; + }; - // This gets called from jquery-ui so we have to manually apply changes to scope - $scope.buildPaletteLists = function() { - $timeout(function() { - $scope.$apply(function() { - buildPaletteLists(); - }); + // This gets called from jquery-ui so we have to manually apply changes to scope + $scope.buildPaletteLists = function() { + $timeout(function() { + $scope.$apply(function() { + buildPaletteLists(); }); - }; + }); + }; - // Checks if a field is on the form or set as a value - $scope.fieldInUse = function(fieldName) { - var data = $scope.entity.data || {}; - if (fieldName in data) { - return true; - } - return check($scope.editor.scope.layout['#children'], {'#tag': 'af-field', name: fieldName}); - }; + // Checks if a field is on the form or set as a value + $scope.fieldInUse = function(fieldName) { + var data = ctrl.entity.data || {}; + if (fieldName in data) { + return true; + } + return check(ctrl.editor.layout['#children'], {'#tag': 'af-field', name: fieldName}); + }; - $scope.blockInUse = function(block) { - if (block['af-join']) { - return check($scope.editor.scope.layout['#children'], {'af-join': block['af-join']}); - } - var fieldsInBlock = _.pluck(findRecursive($scope.editor.meta.blocks[block['#tag']].layout, {'#tag': 'af-field'}), 'name'); - return check($scope.editor.scope.layout['#children'], function(item) { - return item['#tag'] === 'af-field' && _.includes(fieldsInBlock, item.name); - }); - }; + $scope.blockInUse = function(block) { + if (block['af-join']) { + return check(ctrl.editor.layout['#children'], {'af-join': block['af-join']}); + } + var fieldsInBlock = _.pluck(findRecursive(ctrl.editor.meta.blocks[block['#tag']].layout, {'#tag': 'af-field'}), 'name'); + return check(ctrl.editor.layout['#children'], function(item) { + return item['#tag'] === 'af-field' && _.includes(fieldsInBlock, item.name); + }); + }; - // Check for a matching item for this entity - // Recursively checks the form layout, including block directives - function check(group, criteria, found) { - if (!found) { - found = {}; - } - if (_.find(group, criteria)) { - found.match = true; - return true; + // Check for a matching item for this entity + // Recursively checks the form layout, including block directives + function check(group, criteria, found) { + if (!found) { + found = {}; + } + if (_.find(group, criteria)) { + found.match = true; + return true; + } + _.each(group, function(item) { + if (found.match) { + return false; } - _.each(group, function(item) { - if (found.match) { - return false; + if (_.isPlainObject(item)) { + // Recurse through everything but skip fieldsets for other entities + if ((!item['af-fieldset'] || (item['af-fieldset'] === ctrl.entity.name)) && item['#children']) { + check(item['#children'], criteria, found); } - if (_.isPlainObject(item)) { - // Recurse through everything but skip fieldsets for other entities - if ((!item['af-fieldset'] || (item['af-fieldset'] === $scope.entity.name)) && item['#children']) { - check(item['#children'], criteria, found); - } - // Recurse into block directives - else if (item['#tag'] && item['#tag'] in $scope.editor.meta.blocks) { - check($scope.editor.meta.blocks[item['#tag']].layout, criteria, found); - } + // Recurse into block directives + else if (item['#tag'] && item['#tag'] in ctrl.editor.meta.blocks) { + check(ctrl.editor.meta.blocks[item['#tag']].layout, criteria, found); } - }); - return found.match; - } - - $scope.$watch('controls.addValue', function(fieldName) { - if (fieldName) { - if (!$scope.entity.data) { - $scope.entity.data = {}; - } - $scope.entity.data[fieldName] = ''; - $scope.controls.addValue = ''; } }); - - $scope.$watch('controls.fieldSearch', buildPaletteLists); + return found.match; } - }; + + $scope.$watch('controls.addValue', function(fieldName) { + if (fieldName) { + if (!ctrl.entity.data) { + ctrl.entity.data = {}; + } + ctrl.entity.data[fieldName] = ''; + $scope.controls.addValue = ''; + } + }); + + $scope.$watch('controls.fieldSearch', buildPaletteLists); + } }); angular.module('afGuiEditor').directive('afGuiContainer', function(crmApi4, dialogService) { diff --git a/ext/afform/admin/ang/afGuiEditor/canvas.html b/ext/afform/admin/ang/afGuiEditor/canvas.html index 29b6b02e80..a5da54094e 100644 --- a/ext/afform/admin/ang/afGuiEditor/canvas.html +++ b/ext/afform/admin/ang/afGuiEditor/canvas.html @@ -25,7 +25,7 @@
-
+

{{:: ts('This is a read-only preview of the auto-generated markup.') }}

diff --git a/ext/afform/admin/ang/afGuiEditor/entity.html b/ext/afform/admin/ang/afGuiEditor/entity.html index 3310c89eaa..4b95944199 100644 --- a/ext/afform/admin/ang/afGuiEditor/entity.html +++ b/ext/afform/admin/ang/afGuiEditor/entity.html @@ -1,10 +1,10 @@
{{:: ts('Values:') }} -
+

- - + +
@@ -22,7 +22,7 @@
-
+
{{ blockTitles[$index] }}
@@ -30,7 +30,7 @@
-
+
{{ elementTitles[$index] }}
@@ -39,9 +39,9 @@
-
+
- {{ editor.getField(fieldGroup.entityType, field.name).label }} + {{ $ctrl.editor.getField(fieldGroup.entityType, field.name).label }}
@@ -50,11 +50,11 @@
- +
{{:: ts('Options') }} -
+
diff --git a/ext/afform/admin/ang/afGuiEditor/entityConfig/Contact.html b/ext/afform/admin/ang/afGuiEditor/entityConfig/Contact.html index 3bfc2b543e..f81fdda0f7 100644 --- a/ext/afform/admin/ang/afGuiEditor/entityConfig/Contact.html +++ b/ext/afform/admin/ang/afGuiEditor/entityConfig/Contact.html @@ -3,7 +3,7 @@ - diff --git a/ext/afform/admin/ang/afGuiEditor/entityConfig/Generic.html b/ext/afform/admin/ang/afGuiEditor/entityConfig/Generic.html index 646e442e91..1e39d0501f 100644 --- a/ext/afform/admin/ang/afGuiEditor/entityConfig/Generic.html +++ b/ext/afform/admin/ang/afGuiEditor/entityConfig/Generic.html @@ -1,6 +1,6 @@
diff --git a/ext/afform/admin/ang/afGuiEditor/main.html b/ext/afform/admin/ang/afGuiEditor/main.html index 6d6609ede6..a93da817c0 100644 --- a/ext/afform/admin/ang/afGuiEditor/main.html +++ b/ext/afform/admin/ang/afGuiEditor/main.html @@ -1,7 +1,3 @@ -
-
-
-
diff --git a/ext/afform/admin/ang/afGuiEditor/palette.html b/ext/afform/admin/ang/afGuiEditor/palette.html index f3bc071814..8e01c438e0 100644 --- a/ext/afform/admin/ang/afGuiEditor/palette.html +++ b/ext/afform/admin/ang/afGuiEditor/palette.html @@ -22,5 +22,7 @@
-
+
+ +
-- 2.25.1