From 28b4ace49441771740f503e6ef6fe537c8ef2233 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Tue, 5 Nov 2019 21:35:02 -0500 Subject: [PATCH] Save button for gui + api --- .../core/Civi/Api4/Action/Afform/Create.php | 13 ++++ .../core/Civi/Api4/Action/Afform/Get.php | 9 +-- .../core/Civi/Api4/Action/Afform/Save.php | 13 ++++ .../core/Civi/Api4/Action/Afform/Update.php | 64 +---------------- ext/afform/core/Civi/Api4/Afform.php | 59 +++++++++------ .../core/Civi/Api4/Utils/AfformSaveTrait.php | 71 +++++++++++++++++++ ext/afform/gui/ang/afGuiEditor.css | 5 ++ ext/afform/gui/ang/afGuiEditor.js | 21 ++++++ ext/afform/gui/ang/afGuiEditor/canvas.html | 12 +++- 9 files changed, 177 insertions(+), 90 deletions(-) create mode 100644 ext/afform/core/Civi/Api4/Action/Afform/Create.php create mode 100644 ext/afform/core/Civi/Api4/Action/Afform/Save.php create mode 100644 ext/afform/core/Civi/Api4/Utils/AfformSaveTrait.php diff --git a/ext/afform/core/Civi/Api4/Action/Afform/Create.php b/ext/afform/core/Civi/Api4/Action/Afform/Create.php new file mode 100644 index 0000000000..30729f6eaf --- /dev/null +++ b/ext/afform/core/Civi/Api4/Action/Afform/Create.php @@ -0,0 +1,13 @@ +createSiteLocalPath($name, 'aff.html'); - \ CRM_Utils_File::createDir(dirname($layoutPath)); - file_put_contents($layoutPath, $this->convertInputToHtml($updates['layout'])); - // FIXME check for writability then success. Report errors. - } - - // Create or update *.aff.json. - $orig = \Civi\Api4\Afform::get() - ->setCheckPermissions($this->getCheckPermissions()) - ->addWhere('name', '=', $name) - ->execute(); - - if (isset($orig[0])) { - $meta = _afform_fields_filter(array_merge($orig[0], $updates)); - } - else { - $meta = $updates; - } - unset($meta['layout']); - unset($meta['name']); - if (!empty($meta)) { - $metaPath = $scanner->createSiteLocalPath($name, \CRM_Afform_AfformScanner::METADATA_FILE); - // printf("[%s] Update meta %s: %s\n", $name, $metaPath, print_R(['updates'=>$updates, 'meta'=>$meta], 1)); - \CRM_Utils_File::createDir(dirname($metaPath)); - file_put_contents($metaPath, json_encode($meta, JSON_PRETTY_PRINT)); - // FIXME check for writability then success. Report errors. - } - - // We may have changed list of files covered by the cache. - _afform_clear(); - - if (isset($updates['server_route']) && $updates['server_route'] !== $orig[0]['server_route']) { - \CRM_Core_Menu::store(); - \CRM_Core_BAO_Navigation::resetNavigation(); - } - // FIXME if `server_route` changes, then flush the menu cache. - // FIXME if asset-caching is enabled, then flush the asset cache. +class Update extends \Civi\Api4\Generic\BasicUpdateAction { - return $updates; - } + use \Civi\Api4\Utils\AfformSaveTrait; } diff --git a/ext/afform/core/Civi/Api4/Afform.php b/ext/afform/core/Civi/Api4/Afform.php index 86e26a4d95..8bfecf5b1b 100644 --- a/ext/afform/core/Civi/Api4/Afform.php +++ b/ext/afform/core/Civi/Api4/Afform.php @@ -19,6 +19,41 @@ class Afform extends AbstractEntity { return new \Civi\Api4\Action\Afform\Get('Afform', __FUNCTION__); } + /** + * @return \Civi\Api4\Action\Afform\Create + */ + public static function create() { + return new \Civi\Api4\Action\Afform\Create('Afform', __FUNCTION__); + } + + /** + * @return \Civi\Api4\Action\Afform\Update + */ + public static function update() { + return new \Civi\Api4\Action\Afform\Update('Afform', __FUNCTION__, 'name'); + } + + /** + * @return \Civi\Api4\Action\Afform\Save + */ + public static function save() { + return new \Civi\Api4\Action\Afform\Save('Afform', __FUNCTION__, 'name'); + } + + /** + * @return \Civi\Api4\Action\Afform\Prefill + */ + public static function prefill() { + return new \Civi\Api4\Action\Afform\Prefill('Afform', __FUNCTION__); + } + + /** + * @return \Civi\Api4\Action\Afform\Submit + */ + public static function submit() { + return new \Civi\Api4\Action\Afform\Submit('Afform', __FUNCTION__); + } + /** * @return \Civi\Api4\Generic\BasicBatchAction */ @@ -49,29 +84,8 @@ class Afform extends AbstractEntity { }); } - /** - * @return \Civi\Api4\Action\Afform\Update - */ - public static function update() { - return new \Civi\Api4\Action\Afform\Update('Afform', __FUNCTION__, 'name'); - } - - /** - * @return \Civi\Api4\Action\Afform\Prefill - */ - public static function prefill() { - return new \Civi\Api4\Action\Afform\Prefill('Afform', __FUNCTION__); - } - - /** - * @return \Civi\Api4\Action\Afform\Submit - */ - public static function submit() { - return new \Civi\Api4\Action\Afform\Submit('Afform', __FUNCTION__); - } - public static function getFields() { - return new BasicGetFieldsAction('Afform', __FUNCTION__, function() { + return new BasicGetFieldsAction('Afform', __FUNCTION__, function($self) { return [ [ 'name' => 'name', @@ -81,6 +95,7 @@ class Afform extends AbstractEntity { ], [ 'name' => 'title', + 'required' => $self->getAction() === 'create', ], [ 'name' => 'description', diff --git a/ext/afform/core/Civi/Api4/Utils/AfformSaveTrait.php b/ext/afform/core/Civi/Api4/Utils/AfformSaveTrait.php new file mode 100644 index 0000000000..6322c50d80 --- /dev/null +++ b/ext/afform/core/Civi/Api4/Utils/AfformSaveTrait.php @@ -0,0 +1,71 @@ +createSiteLocalPath($name . $suffix, \CRM_Afform_AfformScanner::METADATA_FILE)) + || file_exists($scanner->createSiteLocalPath($name . $suffix, 'aff.html')) + ) { + $suffix++; + } + $name .= $suffix; + } + elseif (!preg_match('/^[a-zA-Z][a-zA-Z0-9\-]*$/', $name)) { + throw new \API_Exception("Afform.{$this->getActionName()}: name should use alphanumerics and dashes."); + } + + // FIXME validate all field data. + $updates = _afform_fields_filter($item); + + // Create or update aff.html. + if (isset($updates['layout'])) { + $layoutPath = $scanner->createSiteLocalPath($name, 'aff.html'); + \CRM_Utils_File::createDir(dirname($layoutPath)); + file_put_contents($layoutPath, $this->convertInputToHtml($updates['layout'])); + // FIXME check for writability then success. Report errors. + } + + $orig = NULL; + $meta = $updates; + unset($meta['layout']); + unset($meta['name']); + if (!empty($meta)) { + $metaPath = $scanner->createSiteLocalPath($name, \CRM_Afform_AfformScanner::METADATA_FILE); + if (file_exists($metaPath)) { + $orig = $scanner->getMeta($name); + } + \CRM_Utils_File::createDir(dirname($metaPath)); + file_put_contents($metaPath, json_encode($meta, JSON_PRETTY_PRINT)); + // FIXME check for writability then success. Report errors. + } + + // We may have changed list of files covered by the cache. + _afform_clear(); + + if (($updates['server_route'] ?? NULL) !== ($orig['server_route'] ?? NULL)) { + \CRM_Core_Menu::store(); + \CRM_Core_BAO_Navigation::resetNavigation(); + } + // FIXME if asset-caching is enabled, then flush the asset cache. + + return $updates; + } + +} diff --git a/ext/afform/gui/ang/afGuiEditor.css b/ext/afform/gui/ang/afGuiEditor.css index a8e333f82e..540a96fafb 100644 --- a/ext/afform/gui/ang/afGuiEditor.css +++ b/ext/afform/gui/ang/afGuiEditor.css @@ -154,3 +154,8 @@ display: inline-block; width: 300px; } + +#afGuiEditor-canvas .panel-heading .btn-group { + position: relative; + top: -8px; +} diff --git a/ext/afform/gui/ang/afGuiEditor.js b/ext/afform/gui/ang/afGuiEditor.js index acfb5898d3..05a60c422d 100644 --- a/ext/afform/gui/ang/afGuiEditor.js +++ b/ext/afform/gui/ang/afGuiEditor.js @@ -11,6 +11,7 @@ controller: function($scope) { $scope.ts = CRM.ts(); $scope.afform = null; + $scope.saving = false; $scope.selectedEntity = null; $scope.meta = CRM.afformAdminData; $scope.controls = {}; @@ -38,6 +39,7 @@ function initialize(afform) { $scope.afform = afform; + $scope.changesSaved = 1; // Remove empty text nodes, they just create clutter removeRecursive($scope.afform.layout, function(item) { return ('#text' in item) && _.trim(item['#text']).length === 0; @@ -47,6 +49,11 @@ $scope.entities = getTags($scope.layout['#children'], 'af-entity', 'name'); expandFields($scope.layout['#children']); _.each(_.keys($scope.entities), buildFieldList); + + // Set changesSaved to true on initial load, false thereafter whenever changes are made to the model + $scope.$watch('afform', function () { + $scope.changesSaved = $scope.changesSaved === 1; + }, true); } this.addEntity = function(entityType) { @@ -141,6 +148,17 @@ delete entity.data[fieldName]; }; + $scope.save = function() { + $scope.saving = true; + CRM.api4('Afform', 'save', {records: [JSON.parse(angular.toJson($scope.afform))]}) + .then(function () { + $scope.$apply(function () { + $scope.saving = false; + $scope.changesSaved = true; + }); + }); + }; + $scope.$watch('controls.addValue', function(fieldName) { if (fieldName) { if (!$scope.entities[$scope.selectedEntity].data) { @@ -316,6 +334,9 @@ }; $scope.getLayout = function() { + if (!$scope.node) { + return ''; + } return _.intersection(splitClass($scope.node['class']), _.keys($scope.layouts))[0] || 'af-layout-rows'; }; diff --git a/ext/afform/gui/ang/afGuiEditor/canvas.html b/ext/afform/gui/ang/afGuiEditor/canvas.html index 8d0eda2044..37d7967506 100644 --- a/ext/afform/gui/ang/afGuiEditor/canvas.html +++ b/ext/afform/gui/ang/afGuiEditor/canvas.html @@ -1,6 +1,16 @@
- {{ ts('Form Layout') }} +
+
+ +
+
{{ ts('Form Layout') }}
+
-- 2.25.1