From 954703502f5b850dc3fb035b54365d01dc44bf9c Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Sun, 5 May 2019 00:05:07 -0700 Subject: [PATCH] core - Implement aff-api4-action directive This allows you to invoke APIv4 when a user clicks on a button or link. It is analogous to `ng-click`, except that the notation and messaging are tweaked for APIv4. --- ext/afform/core/ang/afformCore.ang.php | 2 +- ext/afform/core/ang/afformCore.css | 7 ++++ ext/afform/core/ang/afformCore.js | 3 +- ext/afform/core/ang/afformCore/Api4Action.js | 31 ++++++++++++++++++ ext/afform/core/ang/afformCore/Api4Action.md | 34 ++++++++++++++++++++ ext/afform/docs/roadmap.md | 1 + 6 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 ext/afform/core/ang/afformCore.css create mode 100644 ext/afform/core/ang/afformCore/Api4Action.js create mode 100644 ext/afform/core/ang/afformCore/Api4Action.md diff --git a/ext/afform/core/ang/afformCore.ang.php b/ext/afform/core/ang/afformCore.ang.php index 2a02341632..c93f304502 100644 --- a/ext/afform/core/ang/afformCore.ang.php +++ b/ext/afform/core/ang/afformCore.ang.php @@ -9,7 +9,7 @@ return array( 1 => 'ang/afformCore/*.js', 2 => 'ang/afformCore/*/*.js', ), - 'css' => array(), + 'css' => array('ang/afformCore.css'), 'requires' => array('crmUi', 'crmUtil', 'api4'), 'partials' => array('ang/afformCore'), 'settings' => array(), diff --git a/ext/afform/core/ang/afformCore.css b/ext/afform/core/ang/afformCore.css new file mode 100644 index 0000000000..d5a9b31fcb --- /dev/null +++ b/ext/afform/core/ang/afformCore.css @@ -0,0 +1,7 @@ +.aff-api4-action-running { + cursor: not-allowed; + color: black; +} +a.aff-api4-action-idle { + cursor: pointer; +} diff --git a/ext/afform/core/ang/afformCore.js b/ext/afform/core/ang/afformCore.js index afad2607e2..9c12c157a4 100644 --- a/ext/afform/core/ang/afformCore.js +++ b/ext/afform/core/ang/afformCore.js @@ -5,7 +5,7 @@ ]); // Use `afformCoreDirective(string name)` to generate an AngularJS directive. - angular.module('afformCore').service('afformCoreDirective', function($routeParams, crmApi4, crmStatus){ + angular.module('afformCore').service('afformCoreDirective', function($routeParams, crmApi4, crmStatus, crmUiAlert){ return function(camelName, meta, d){ d.restrict = 'AE'; d.scope = {}; @@ -16,6 +16,7 @@ $scope.meta = meta; $scope.crmApi4 = crmApi4; $scope.crmStatus = crmStatus; + $scope.crmUiAlert = crmUiAlert; }; return d; }; diff --git a/ext/afform/core/ang/afformCore/Api4Action.js b/ext/afform/core/ang/afformCore/Api4Action.js new file mode 100644 index 0000000000..b68b729ce3 --- /dev/null +++ b/ext/afform/core/ang/afformCore/Api4Action.js @@ -0,0 +1,31 @@ +(function(angular, $, _) { + + angular.module('afformCore').directive('affApi4Action', function($parse, crmStatus, crmApi4) { + return { + restrict: 'A', + scope: { + affApi4Action: '@', + msgStart: '=', + msgError: '=', + msgSuccess: '=', + onSuccess: '@', + onError: '@' + }, + link: function($scope, $el, $attr) { + var ts = CRM.ts(null); + function running(x) {$el.toggleClass('aff-api4-action-running', x).toggleClass('aff-api4-action-idle', !x);} + running(false); + $el.click(function(){ + var parts = $parse($scope.affApi4Action)($scope.$parent); + var msgs = {start: $scope.msgStart || ts('Submitting...'), success: $scope.msgSuccess, error: $scope.msgError}; + running(true); + crmStatus(msgs, crmApi4(parts[0], parts[1], parts[2])) + .finally(function(){running(false);}) + .then(function(response){$scope.$parent.$eval($scope.onSuccess, {response: response});}) + .catch(function(error){$scope.$parent.$eval($scope.onError, {error: error});}); + }); + } + }; + }); + +})(angular, CRM.$, CRM._); diff --git a/ext/afform/core/ang/afformCore/Api4Action.md b/ext/afform/core/ang/afformCore/Api4Action.md new file mode 100644 index 0000000000..d1f4f810e2 --- /dev/null +++ b/ext/afform/core/ang/afformCore/Api4Action.md @@ -0,0 +1,34 @@ +# aff-api4-action + +This directive is designed for invoking an action via APIv4. Much like +`ng-click`, one would use `api4-action` to add behavior to a button or link. + +```html + +``` + +### Options + +Additional options may be used to manipulate the status messages and to +trigger further actions on failure or success. + +```html + + +``` + +### Styling + +The `aff-api4-action` element will have the follow classes +toggled automatically: + +* `aff-api4-action-running`: User has clicked to fire the action, and action is still running. +* `aff-api4-action-idle`: The action is not running. diff --git a/ext/afform/docs/roadmap.md b/ext/afform/docs/roadmap.md index 3ef1bd771f..ab8639a1fc 100644 --- a/ext/afform/docs/roadmap.md +++ b/ext/afform/docs/roadmap.md @@ -24,6 +24,7 @@ This extension is expected to be the base for a suite of related extensions: Within this extension, there are things which need updating/addressing: +* Test coverage for key Angular directives (e.g. `aff-api4-ctrl`, `aff-api4-action`) * There are several `FIXME`/`TODO` declarations in the code for checking pre-conditions, reporting errors, handling edge-cases, etc. * Although afforms can be used in AngularJS, they don't fully support tooling like `cv ang:html:list` and `hook_civicrm_alterAngular` changesets. We'll need a core patch to allow that. (Ex: Define partials via callback.) -- 2.25.1