0953d61916313b0c51bf484545713b145847e511
1 // https://civicrm.org/licensing
2 (function(angular
, $, _
) {
5 angular
.module('afGuiEditor').component('afGuiContainer', {
6 templateUrl
: '~/afGuiEditor/elements/afGuiContainer.html',
13 require
: {editor
: '^^afGuiEditor'},
14 controller: function($scope
, crmApi4
, dialogService
, afGui
) {
15 var ts
= $scope
.ts
= CRM
.ts(),
18 this.$onInit = function() {
19 if ((ctrl
.node
['#tag'] in afGui
.meta
.blocks
) || ctrl
.join
) {
20 var blockNode
= getBlockNode(),
21 blockTag
= blockNode
? blockNode
['#tag'] : null;
22 if (blockTag
&& (blockTag
in afGui
.meta
.blocks
) && !afGui
.meta
.blocks
[blockTag
].layout
) {
24 crmApi4('Afform', 'loadAdminData', {
25 definition
: {name
: afGui
.meta
.blocks
[blockTag
].name
}
26 }, 0).then(function(data
) {
28 initializeBlockContainer();
32 initializeBlockContainer();
36 $scope
.isSelectedFieldset = function(entityName
) {
37 return entityName
=== ctrl
.editor
.getSelectedEntityName();
40 $scope
.selectEntity = function() {
41 if (ctrl
.node
['af-fieldset']) {
42 ctrl
.editor
.selectEntity(ctrl
.node
['af-fieldset']);
48 fieldset
: ts('Fieldset')
55 $scope
.getSetChildren = function(val
) {
56 var collection
= block
.layout
|| (ctrl
.node
&& ctrl
.node
['#children']);
57 return arguments
.length
? (collection
= val
) : collection
;
60 $scope
.isRepeatable = function() {
61 return ctrl
.node
['af-fieldset'] || (block
.directive
&& afGui
.meta
.blocks
[block
.directive
].repeat
) || ctrl
.join
;
64 $scope
.toggleRepeat = function() {
65 if ('af-repeat' in ctrl
.node
) {
68 delete ctrl
.node
['af-repeat'];
69 delete ctrl
.node
['add-icon'];
72 ctrl
.node
['af-repeat'] = ts('Add');
76 $scope
.getSetMin = function(val
) {
77 if (arguments
.length
) {
78 if (ctrl
.node
.max
&& val
> parseInt(ctrl
.node
.max
, 10)) {
79 ctrl
.node
.max
= '' + val
;
85 ctrl
.node
.min
= '' + val
;
88 return ctrl
.node
.min
? parseInt(ctrl
.node
.min
, 10) : null;
91 $scope
.getSetMax = function(val
) {
92 if (arguments
.length
) {
93 if (ctrl
.node
.min
&& val
&& val
< parseInt(ctrl
.node
.min
, 10)) {
94 ctrl
.node
.min
= '' + val
;
96 if (typeof val
!== 'number') {
100 ctrl
.node
.max
= '' + val
;
103 return ctrl
.node
.max
? parseInt(ctrl
.node
.max
, 10) : null;
106 $scope
.pickAddIcon = function() {
107 afGui
.pickIcon().then(function(val
) {
108 ctrl
.node
['add-icon'] = val
;
112 function getBlockNode() {
113 return !ctrl
.join
? ctrl
.node
: (ctrl
.node
['#children'] && ctrl
.node
['#children'].length
=== 1 ? ctrl
.node
['#children'][0] : null);
116 function setBlockDirective(directive
) {
118 ctrl
.node
['#children'] = [{'#tag': directive
}];
120 delete ctrl
.node
['#children'];
121 delete ctrl
.node
['class'];
122 ctrl
.node
['#tag'] = directive
;
126 function overrideBlockContents(layout
) {
127 ctrl
.node
['#children'] = layout
|| [];
129 ctrl
.node
['#tag'] = 'div';
130 ctrl
.node
['class'] = 'af-container';
132 block
.layout
= block
.directive
= null;
136 'af-layout-rows': ts('Contents display as rows'),
137 'af-layout-cols': ts('Contents are evenly-spaced columns'),
138 'af-layout-inline': ts('Contents are arranged inline')
141 $scope
.getLayout = function() {
145 return _
.intersection(afGui
.splitClass(ctrl
.node
['class']), _
.keys($scope
.layouts
))[0] || 'af-layout-rows';
148 $scope
.setLayout = function(val
) {
149 var classes
= ['af-container'];
150 if (val
!== 'af-layout-rows') {
153 afGui
.modifyClasses(ctrl
.node
, _
.keys($scope
.layouts
), classes
);
156 $scope
.selectBlockDirective = function() {
157 if (block
.directive
) {
158 block
.layout
= _
.cloneDeep(afGui
.meta
.blocks
[block
.directive
].layout
);
159 block
.original
= block
.directive
;
160 setBlockDirective(block
.directive
);
163 overrideBlockContents(block
.layout
);
167 function initializeBlockContainer() {
169 // Cancel the below $watch expressions if already set
170 _
.each(block
.listeners
, function(deregister
) {
174 block
= $scope
.block
= {
182 _
.each(afGui
.meta
.blocks
, function(blockInfo
, directive
) {
183 if (directive
=== ctrl
.node
['#tag'] || blockInfo
.join
=== ctrl
.getFieldEntityType()) {
186 text
: blockInfo
.title
191 if (getBlockNode() && getBlockNode()['#tag'] in afGui
.meta
.blocks
) {
192 block
.directive
= block
.original
= getBlockNode()['#tag'];
193 block
.layout
= _
.cloneDeep(afGui
.meta
.blocks
[block
.directive
].layout
);
196 block
.listeners
.push($scope
.$watch('block.layout', function (layout
, oldVal
) {
197 if (block
.directive
&& layout
&& layout
!== oldVal
&& !angular
.equals(layout
, afGui
.meta
.blocks
[block
.directive
].layout
)) {
198 overrideBlockContents(block
.layout
);
203 $scope
.saveBlock = function() {
204 var options
= CRM
.utils
.adjustDialogDefaults({
208 title
: ts('Save block')
213 layout
: ctrl
.node
['#children']
216 model
.join
= ctrl
.join
;
218 if ($scope
.block
&& $scope
.block
.original
) {
219 model
.title
= afGui
.meta
.blocks
[$scope
.block
.original
].title
;
220 model
.name
= afGui
.meta
.blocks
[$scope
.block
.original
].name
;
221 model
.block
= afGui
.meta
.blocks
[$scope
.block
.original
].block
;
224 model
.block
= ctrl
.container
.getFieldEntityType() || '*';
226 dialogService
.open('saveBlockDialog', '~/afGuiEditor/saveBlock.html', model
, options
)
227 .then(function(block
) {
228 afGui
.meta
.blocks
[block
.directive_name
] = block
;
229 setBlockDirective(block
.directive_name
);
230 initializeBlockContainer();
234 this.node
= ctrl
.node
;
236 this.getNodeType = function(node
) {
240 if (node
['#tag'] === 'af-field') {
243 if (node
['af-fieldset']) {
246 if (node
['af-join']) {
249 if (node
['#tag'] && node
['#tag'] in afGui
.meta
.blocks
) {
252 var classes
= afGui
.splitClass(node
['class']),
253 types
= ['af-container', 'af-text', 'af-button', 'af-markup'],
254 type
= _
.intersection(types
, classes
);
255 return type
.length
? type
[0].replace('af-', '') : null;
258 this.removeElement = function(element
) {
259 afGui
.removeRecursive($scope
.getSetChildren(), {$$hashKey
: element
.$$hashKey
});
262 this.getEntityName = function() {
263 return ctrl
.entityName
.split('-join-')[0];
266 // Returns the primary entity type for this container e.g. "Contact"
267 this.getMainEntityType = function() {
268 return ctrl
.editor
&& ctrl
.editor
.getEntity(ctrl
.getEntityName()).type
;
271 // Returns the entity type for fields within this conainer (join entity type if this is a join, else the primary entity type)
272 this.getFieldEntityType = function() {
273 var joinType
= ctrl
.entityName
.split('-join-');
274 return joinType
[1] || (ctrl
.editor
&& ctrl
.editor
.getEntity(joinType
[0]).type
);
280 })(angular
, CRM
.$, CRM
._
);