From: Coleman Watts Date: Wed, 25 Aug 2021 13:25:18 +0000 (-0400) Subject: Afform - Selectable location_type, is_primary, etc. X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=1f0461e7a6a7451dfffee8ce87fffb17ea3842ea;p=civicrm-core.git Afform - Selectable location_type, is_primary, etc. This allows the user to set a join block (email, phone, address, etc) as either repeatable OR with a set value for is_primary or location_type. Fixes dev/core#2703 --- diff --git a/ext/afform/admin/afformEntities/Address.php b/ext/afform/admin/afformEntities/Address.php index a8a35545a2..0b07aeafba 100644 --- a/ext/afform/admin/afformEntities/Address.php +++ b/ext/afform/admin/afformEntities/Address.php @@ -2,4 +2,5 @@ return [ 'type' => 'join', 'repeat_max' => NULL, + 'unique_fields' => ['is_primary', 'location_type_id'], ]; diff --git a/ext/afform/admin/afformEntities/Email.php b/ext/afform/admin/afformEntities/Email.php index a8a35545a2..0b07aeafba 100644 --- a/ext/afform/admin/afformEntities/Email.php +++ b/ext/afform/admin/afformEntities/Email.php @@ -2,4 +2,5 @@ return [ 'type' => 'join', 'repeat_max' => NULL, + 'unique_fields' => ['is_primary', 'location_type_id'], ]; diff --git a/ext/afform/admin/afformEntities/IM.php b/ext/afform/admin/afformEntities/IM.php index a8a35545a2..0b07aeafba 100644 --- a/ext/afform/admin/afformEntities/IM.php +++ b/ext/afform/admin/afformEntities/IM.php @@ -2,4 +2,5 @@ return [ 'type' => 'join', 'repeat_max' => NULL, + 'unique_fields' => ['is_primary', 'location_type_id'], ]; diff --git a/ext/afform/admin/afformEntities/Phone.php b/ext/afform/admin/afformEntities/Phone.php index a8a35545a2..0b07aeafba 100644 --- a/ext/afform/admin/afformEntities/Phone.php +++ b/ext/afform/admin/afformEntities/Phone.php @@ -2,4 +2,5 @@ return [ 'type' => 'join', 'repeat_max' => NULL, + 'unique_fields' => ['is_primary', 'location_type_id'], ]; diff --git a/ext/afform/admin/afformEntities/Website.php b/ext/afform/admin/afformEntities/Website.php index a8a35545a2..c646f06870 100644 --- a/ext/afform/admin/afformEntities/Website.php +++ b/ext/afform/admin/afformEntities/Website.php @@ -2,4 +2,5 @@ return [ 'type' => 'join', 'repeat_max' => NULL, + 'unique_fields' => ['website_type_id'], ]; diff --git a/ext/afform/admin/ang/afGuiEditor.css b/ext/afform/admin/ang/afGuiEditor.css index a18dc73834..cd75a4411a 100644 --- a/ext/afform/admin/ang/afGuiEditor.css +++ b/ext/afform/admin/ang/afGuiEditor.css @@ -260,13 +260,14 @@ body.af-gui-dragging { opacity: 1; transition: opacity 0s; } -#afGuiEditor #afGuiEditor-canvas .af-entity-selected > .af-gui-bar > .form-inline > button > span, +/* Fix button colors when bar is highlighted */ +#afGuiEditor #afGuiEditor-canvas .af-entity-selected > .af-gui-bar > .form-inline > .btn-group > .btn-group > button > span, #afGuiEditor #afGuiEditor-canvas .af-entity-selected > .af-gui-bar > .form-inline > span { color: white; } -#afGuiEditor #afGuiEditor-canvas .af-entity-selected > .af-gui-bar > .form-inline > button:hover > span, -#afGuiEditor #afGuiEditor-canvas .af-entity-selected > .af-gui-bar > .open > button > span, -#afGuiEditor #afGuiEditor-canvas .af-entity-selected > .af-gui-bar > .form-inline > button:focus > span { +#afGuiEditor #afGuiEditor-canvas .af-entity-selected > .af-gui-bar > .form-inline > .btn-group > .btn-group > button:hover > span, +#afGuiEditor #afGuiEditor-canvas .af-entity-selected > .af-gui-bar > .form-inline > .btn-group > .btn-group > button[aria-expanded=true] > span, +#afGuiEditor #afGuiEditor-canvas .af-entity-selected > .af-gui-bar > .form-inline > .btn-group > .btn-group > button:focus > span { color: #0071bd; } diff --git a/ext/afform/admin/ang/afGuiEditor/afGuiContainerMultiToggle.component.js b/ext/afform/admin/ang/afGuiEditor/afGuiContainerMultiToggle.component.js new file mode 100644 index 0000000000..cd3ff7eac7 --- /dev/null +++ b/ext/afform/admin/ang/afGuiEditor/afGuiContainerMultiToggle.component.js @@ -0,0 +1,115 @@ +// https://civicrm.org/licensing +(function(angular, $, _) { + "use strict"; + + // Menu item to control the border property of a node + angular.module('afGuiEditor').component('afGuiContainerMultiToggle', { + templateUrl: '~/afGuiEditor/afGuiContainerMultiToggle.html', + bindings: { + entity: '<' + }, + require: { + container: '^^afGuiContainer' + }, + controller: function($scope, afGui) { + var ts = $scope.ts = CRM.ts('org.civicrm.afform_admin'), + ctrl = this; + this.menuItems = []; + this.uniqueFields = {}; + + this.$onInit = function() { + this.menuItems.push({ + key: 'repeat', + label: ts('Multiple') + }); + _.each(afGui.getEntity(this.entity).unique_fields, function(fieldName) { + var field = ctrl.uniqueFields[fieldName] = afGui.getField(ctrl.entity, fieldName); + ctrl.menuItems.push({}); + if (field.options) { + _.each(field.options, function(option) { + ctrl.menuItems.push({ + field: fieldName, + key: option.id, + label: option.label + }); + }); + } else { + ctrl.menuItems.push({ + field: fieldName, + key: true, + label: field.label + }); + } + }); + }; + + this.isMulti = function() { + return 'af-repeat' in ctrl.container.node; + }; + + this.isSelected = function(item) { + if (!item.field && item.key === 'repeat') { + return ctrl.isMulti(); + } + if (ctrl.container.node.data) { + var field = ctrl.uniqueFields[item.field]; + if (field.options) { + return ctrl.container.node.data[item.field] === item.key; + } + return ctrl.container.node.data[item.field]; + } + return false; + }; + + this.selectOption = function(item) { + if (!item.field && item.key === 'repeat') { + return ctrl.container.toggleRepeat(); + } + if (ctrl.isMulti()) { + ctrl.container.toggleRepeat(); + } + var field = ctrl.uniqueFields[item.field]; + ctrl.container.node.data = ctrl.container.node.data || {}; + if (field.options) { + if (ctrl.container.node.data[item.field] === item.key) { + delete ctrl.container.node.data[item.field]; + } else { + ctrl.container.node.data = {}; + ctrl.container.node.data[item.field] = item.key; + ctrl.container.removeField(item.field); + } + } else if (ctrl.container.node.data[item.field]) { + delete ctrl.container.node.data[item.field]; + } else { + ctrl.container.node.data = {}; + ctrl.container.node.data[item.field] = true; + ctrl.container.removeField(item.field); + } + if (_.isEmpty(ctrl.container.node.data)) { + delete ctrl.container.node.data; + } + }; + + this.getButtonText = function() { + if (ctrl.isMulti()) { + return ts('Multiple'); + } + var output = ts('Single'); + _.each(ctrl.container.node.data, function(val, fieldName) { + if (val && (fieldName in ctrl.uniqueFields)) { + var field = ctrl.uniqueFields[fieldName]; + if (field.options) { + output = _.result(_.findWhere(field.options, {id: val}), 'label'); + } else { + output = field.label; + } + return false; + } + }); + return output; + }; + + } + }); + +})(angular, CRM.$, CRM._); diff --git a/ext/afform/admin/ang/afGuiEditor/afGuiContainerMultiToggle.html b/ext/afform/admin/ang/afGuiEditor/afGuiContainerMultiToggle.html new file mode 100644 index 0000000000..0d1fdc80f2 --- /dev/null +++ b/ext/afform/admin/ang/afGuiEditor/afGuiContainerMultiToggle.html @@ -0,0 +1,14 @@ + + diff --git a/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer-menu.html b/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer-menu.html index 4a9b6d6fb7..182e092e83 100644 --- a/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer-menu.html +++ b/ext/afform/admin/ang/afGuiEditor/elements/afGuiContainer-menu.html @@ -10,7 +10,7 @@
  • -