From 1b745abc504486a34b1ce1b52051dec70a0601a4 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Mon, 11 Nov 2019 22:20:12 -0500 Subject: [PATCH] GUI: Entity config --- ext/afform/gui/afform_gui.php | 63 +++++++++---------- ext/afform/gui/ang/afGuiEditor.js | 18 ++++-- ext/afform/gui/ang/afGuiEditor/entity.html | 3 +- .../afGuiEditor/entityConfig/Activity.html | 1 + .../ang/afGuiEditor/entityConfig/Contact.html | 10 +++ .../ang/afGuiEditor/entityConfig/Generic.html | 6 ++ .../afGuiEditor/entityDefaults/Activity.json | 5 ++ .../afGuiEditor/entityDefaults/Contact.json | 9 +++ 8 files changed, 77 insertions(+), 38 deletions(-) create mode 100644 ext/afform/gui/ang/afGuiEditor/entityConfig/Activity.html create mode 100644 ext/afform/gui/ang/afGuiEditor/entityConfig/Contact.html create mode 100644 ext/afform/gui/ang/afGuiEditor/entityConfig/Generic.html create mode 100644 ext/afform/gui/ang/afGuiEditor/entityDefaults/Activity.json create mode 100644 ext/afform/gui/ang/afGuiEditor/entityDefaults/Contact.json diff --git a/ext/afform/gui/afform_gui.php b/ext/afform/gui/afform_gui.php index 5aef321d40..1994e9be98 100644 --- a/ext/afform/gui/afform_gui.php +++ b/ext/afform/gui/afform_gui.php @@ -160,44 +160,41 @@ function afform_gui_civicrm_buildAsset($asset, $params, &$mimeType, &$content) { return; } - // Things that can't be handled by afform. TODO: Need a better way to do this. Maybe add core metadata about what each entity is for, and filter on that. - $entityBlacklist = [ - 'ACL', - 'ActionSchedule', - 'ActivityContact', - 'Afform%', - 'CaseContact', - 'EntityTag', - 'GroupContact', - 'GroupNesting', - 'GroupOrganization', - 'Setting', - 'System', - 'UF%', - ]; - $entityApi = Civi\Api4\Entity::get() - ->setCheckPermissions(FALSE) - ->setSelect(['name', 'description']); - foreach ($entityBlacklist as $nono) { - $entityApi->addWhere('name', 'NOT LIKE', $nono); + $entityWhitelist = $data = []; + + // First scan the entityDefaults directory for our list of supported entities + // FIXME: Need a way to load this from other extensions too + foreach (glob(__DIR__ . '/ang/afGuiEditor/entityDefaults/*.json') as $file) { + $matches = []; + preg_match('/([-a-z_A-Z0-9]*).json/', $file, $matches); + $entityWhitelist[] = $entity = $matches[1]; + // No json_decode, the files are not strict json and will go through angular.$parse clientside + $data['defaults'][$entity] = trim(CRM_Utils_JS::stripComments(file_get_contents($file))); } - $contactFields = Civi\Api4\Contact::getFields() + $data['entities'] = (array) Civi\Api4\Entity::get() ->setCheckPermissions(FALSE) - ->setIncludeCustom(TRUE) - ->setLoadOptions(TRUE) - ->setAction('create') - ->setSelect(['name', 'title', 'input_type', 'input_attrs', 'options']) + ->setSelect(['name', 'description']) + ->addWhere('name', 'IN', $entityWhitelist) ->execute(); - $contactSettings = [ - 'data' => [], - ]; + foreach ($entityWhitelist as $entityName) { + $api = 'Civi\\Api4\\' . $entityName; + $data['fields'][$entityName] = (array) $api::getFields() + ->setCheckPermissions(FALSE) + ->setIncludeCustom(TRUE) + ->setLoadOptions(TRUE) + ->setAction('create') + ->setSelect(['name', 'title', 'input_type', 'input_attrs', 'options']) + ->addWhere('input_type', 'IS NOT NULL') + ->execute() + ->indexBy('name'); + } + + // Now adjust the field metadata + // FIXME: This should probably be a callback event or something to allow extensions to tweak the metadata for their entities + $data['fields']['Contact']['contact_type']['required_data'] = TRUE; $mimeType = 'text/javascript'; - $content = "CRM.afformAdminData={"; - $content .= 'entities:' . json_encode((array) $entityApi->execute(), JSON_UNESCAPED_SLASHES) . ','; - $content .= 'fields:' . json_encode(['Contact' => (array) $contactFields], JSON_UNESCAPED_SLASHES) . ','; - $content .= 'settings:' . json_encode(['Contact' => $contactSettings], JSON_UNESCAPED_SLASHES); - $content .= '}'; + $content = "CRM.afformAdminData=" . json_encode($data, JSON_UNESCAPED_SLASHES) . ';'; } diff --git a/ext/afform/gui/ang/afGuiEditor.js b/ext/afform/gui/ang/afGuiEditor.js index eb9009c811..7322a8367d 100644 --- a/ext/afform/gui/ang/afGuiEditor.js +++ b/ext/afform/gui/ang/afGuiEditor.js @@ -87,12 +87,12 @@ while (_.contains(existingEntitiesofThisType, entityType + num)) { num++; } - $scope.entities[entityType + num] = { + $scope.entities[entityType + num] = _.assign($parse(this.meta.defaults[entityType])($scope), { '#tag': 'af-entity', type: entityType, name: entityType + num, label: entityType + ' ' + num - }; + }); $scope.layout['#children'].unshift($scope.entities[entityType + num]); $scope.layout['#children'].push({ '#tag': 'fieldset', @@ -124,7 +124,7 @@ }; this.getField = function(entityType, fieldName) { - return _.filter($scope.meta.fields[entityType], {name: fieldName})[0]; + return $scope.meta.fields[entityType][fieldName]; }; this.getEntity = function(entityName) { @@ -151,6 +151,16 @@ }); }; + $scope.$watch('afform.title', function(newTitle, oldTitle) { + if (typeof oldTitle === 'string') { + _.each($scope.entities, function(entity) { + if (entity.data && entity.data.source === oldTitle) { + entity.data.source = newTitle; + } + }); + } + }); + // Parse strings of javascript that php couldn't interpret function evaluate(collection) { _.each(collection, function(item) { @@ -505,7 +515,7 @@ }; $scope.setStyle = function(val) { - $scope.block.modifyClasses($scope.node, _.keys($scope.styles), val); + $scope.block.modifyClasses($scope.node, _.keys($scope.styles), ['btn', val]); }; $scope.pickIcon = function() { diff --git a/ext/afform/gui/ang/afGuiEditor/entity.html b/ext/afform/gui/ang/afGuiEditor/entity.html index 3359340867..6c86b85927 100644 --- a/ext/afform/gui/ang/afGuiEditor/entity.html +++ b/ext/afform/gui/ang/afGuiEditor/entity.html @@ -4,7 +4,7 @@

- +
@@ -36,4 +36,5 @@
{{ ts('Options') }} +
diff --git a/ext/afform/gui/ang/afGuiEditor/entityConfig/Activity.html b/ext/afform/gui/ang/afGuiEditor/entityConfig/Activity.html new file mode 100644 index 0000000000..15e56f1cbe --- /dev/null +++ b/ext/afform/gui/ang/afGuiEditor/entityConfig/Activity.html @@ -0,0 +1 @@ +
diff --git a/ext/afform/gui/ang/afGuiEditor/entityConfig/Contact.html b/ext/afform/gui/ang/afGuiEditor/entityConfig/Contact.html new file mode 100644 index 0000000000..252b9c3457 --- /dev/null +++ b/ext/afform/gui/ang/afGuiEditor/entityConfig/Contact.html @@ -0,0 +1,10 @@ +
+
+ + +
diff --git a/ext/afform/gui/ang/afGuiEditor/entityConfig/Generic.html b/ext/afform/gui/ang/afGuiEditor/entityConfig/Generic.html new file mode 100644 index 0000000000..88db90cd9c --- /dev/null +++ b/ext/afform/gui/ang/afGuiEditor/entityConfig/Generic.html @@ -0,0 +1,6 @@ +
+ +
diff --git a/ext/afform/gui/ang/afGuiEditor/entityDefaults/Activity.json b/ext/afform/gui/ang/afGuiEditor/entityDefaults/Activity.json new file mode 100644 index 0000000000..41288d8351 --- /dev/null +++ b/ext/afform/gui/ang/afGuiEditor/entityDefaults/Activity.json @@ -0,0 +1,5 @@ +// Default values for creating a new entity. +// Note this is not strict JSON - it passes through angular.$parse - $scope variables are available. +{ + 'url-autofill': '1' +} diff --git a/ext/afform/gui/ang/afGuiEditor/entityDefaults/Contact.json b/ext/afform/gui/ang/afGuiEditor/entityDefaults/Contact.json new file mode 100644 index 0000000000..2ffa077220 --- /dev/null +++ b/ext/afform/gui/ang/afGuiEditor/entityDefaults/Contact.json @@ -0,0 +1,9 @@ +// Default values for creating a new entity. +// Note this is not strict JSON - it passes through angular.$parse - $scope variables are available. +{ + data: { + contact_type: 'Individual', + source: afform.title + }, + 'url-autofill': '1' +} -- 2.25.1