1 // https://civicrm.org/licensing
2 (function(angular
, $, _
) {
5 angular
.module('afGuiEditor').component('afGuiEntity', {
6 templateUrl
: '~/afGuiEditor/afGuiEntity.html',
10 require
: {editor
: '^^afGuiEditor'},
11 controller: function ($scope
, $timeout
, afGui
) {
12 var ts
= $scope
.ts
= CRM
.ts('org.civicrm.afform_admin');
15 $scope
.fieldList
= [];
16 $scope
.blockList
= [];
17 $scope
.blockTitles
= [];
18 $scope
.elementList
= [];
19 $scope
.elementTitles
= [];
21 this.getEntityType = function() {
22 return (ctrl
.entity
.type
=== 'Contact' && ctrl
.entity
.data
) ? ctrl
.entity
.data
.contact_type
|| 'Contact' : ctrl
.entity
.type
;
25 $scope
.getMeta = function() {
26 return afGui
.meta
.entities
[ctrl
.getEntityType()];
29 $scope
.getAdminTpl = function() {
30 return $scope
.getMeta().admin_tpl
|| '~/afGuiEditor/entityConfig/Generic.html';
33 $scope
.getField
= afGui
.getField
;
35 $scope
.valuesFields = function() {
36 var fields
= _
.transform($scope
.getMeta().fields
, function(fields
, field
) {
37 fields
.push({id
: field
.name
, text
: field
.label
, disabled
: $scope
.fieldInUse(field
.name
)});
39 return {results
: fields
};
42 $scope
.removeValue = function(entity
, fieldName
) {
43 delete entity
.data
[fieldName
];
46 this.buildPaletteLists = function() {
47 var search
= $scope
.controls
.fieldSearch
? $scope
.controls
.fieldSearch
.toLowerCase() : null;
48 buildFieldList(search
);
49 buildBlockList(search
);
50 buildElementList(search
);
53 function buildFieldList(search
) {
54 $scope
.fieldList
.length
= 0;
55 $scope
.fieldList
.push({
56 entityName
: ctrl
.entity
.name
,
57 entityType
: ctrl
.getEntityType(),
58 label
: ts('%1 Fields', {1: $scope
.getMeta().label
}),
59 fields
: filterFields($scope
.getMeta().fields
)
61 // Add fields for af-join blocks
62 _
.each(afGui
.meta
.entities
, function(entity
, entityName
) {
63 if (check(ctrl
.editor
.layout
['#children'], {'af-join': entityName
})) {
64 $scope
.fieldList
.push({
65 entityName
: ctrl
.entity
.name
+ '-join-' + entityName
,
66 entityType
: entityName
,
67 label
: ts('%1 Fields', {1: entity
.label
}),
68 fields
: filterFields(entity
.fields
)
73 function filterFields(fields
) {
74 return _
.transform(fields
, function(fieldList
, field
) {
75 if (!field
.readonly
&&
76 (!search
|| _
.contains(field
.name
, search
) || _
.contains(field
.label
.toLowerCase(), search
))
78 fieldList
.push(fieldDefaults(field
));
83 function fieldDefaults(field
) {
92 function buildBlockList(search
) {
93 $scope
.blockList
.length
= 0;
94 $scope
.blockTitles
.length
= 0;
95 _
.each(afGui
.meta
.blocks
, function(block
, directive
) {
96 if ((!search
|| _
.contains(directive
, search
) || _
.contains(block
.name
.toLowerCase(), search
) || _
.contains(block
.title
.toLowerCase(), search
)) &&
97 (block
.entity_type
=== '*' || block
.entity_type
=== ctrl
.entity
.type
|| (ctrl
.entity
.type
=== 'Contact' && block
.entity_type
=== ctrl
.entity
.data
.contact_type
)) &&
98 block
.name
!== ctrl
.editor
.getAfform().name
100 var item
= {"#tag": block
.join_entity
? "div" : directive
};
101 if (block
.join_entity
) {
102 item
['af-join'] = block
.join_entity
;
103 item
['#children'] = [{"#tag": directive
}];
106 item
['af-repeat'] = ts('Add');
108 if (typeof block
.repeat
=== 'number') {
109 item
.max
= '' + block
.repeat
;
112 $scope
.blockList
.push(item
);
113 $scope
.blockTitles
.push(block
.title
);
118 function buildElementList(search
) {
119 $scope
.elementList
.length
= 0;
120 $scope
.elementTitles
.length
= 0;
121 _
.each(afGui
.meta
.elements
, function(element
, name
) {
122 if (!search
|| _
.contains(name
, search
) || _
.contains(element
.title
.toLowerCase(), search
)) {
123 var node
= _
.cloneDeep(element
.element
);
124 if (name
=== 'fieldset') {
125 if (!ctrl
.editor
.allowEntityConfig
) {
128 node
['af-fieldset'] = ctrl
.entity
.name
;
130 $scope
.elementList
.push(node
);
131 $scope
.elementTitles
.push(name
=== 'fieldset' ? ts('Fieldset for %1', {1: ctrl
.entity
.label
}) : element
.title
);
136 // This gets called from jquery-ui so we have to manually apply changes to scope
137 $scope
.buildPaletteLists = function() {
138 $timeout(function() {
139 $scope
.$apply(function() {
140 ctrl
.buildPaletteLists();
145 // Checks if a field is on the form or set as a value
146 $scope
.fieldInUse = function(fieldName
) {
147 var data
= ctrl
.entity
.data
|| {};
148 if (fieldName
in data
) {
151 return check(ctrl
.editor
.layout
['#children'], {'#tag': 'af-field', name
: fieldName
});
154 // Checks if fields in a block are already in use on the form.
155 // Note that if a block contains no fields it can be used repeatedly, so this will always return false for those.
156 $scope
.blockInUse = function(block
) {
157 if (block
['af-join']) {
158 return check(ctrl
.editor
.layout
['#children'], {'af-join': block
['af-join']});
160 var fieldsInBlock
= _
.pluck(afGui
.findRecursive(afGui
.meta
.blocks
[block
['#tag']].layout
, {'#tag': 'af-field'}), 'name');
161 return check(ctrl
.editor
.layout
['#children'], function(item
) {
162 return item
['#tag'] === 'af-field' && _
.includes(fieldsInBlock
, item
.name
);
166 // Check for a matching item for this entity
167 // Recursively checks the form layout, including block directives
168 function check(group
, criteria
, found
) {
172 if (_
.find(group
, criteria
)) {
176 _
.each(group
, function(item
) {
180 if (_
.isPlainObject(item
)) {
181 // Recurse through everything but skip fieldsets for other entities
182 if ((!item
['af-fieldset'] || (item
['af-fieldset'] === ctrl
.entity
.name
)) && item
['#children']) {
183 check(item
['#children'], criteria
, found
);
185 // Recurse into block directives
186 else if (item
['#tag'] && item
['#tag'] in afGui
.meta
.blocks
) {
187 check(afGui
.meta
.blocks
[item
['#tag']].layout
, criteria
, found
);
194 this.$onInit = function() {
195 // When a new block is saved, update the list
196 this.meta
= afGui
.meta
;
197 $scope
.$watchCollection('$ctrl.meta.blocks', function() {
198 $scope
.controls
.fieldSearch
= '';
199 ctrl
.buildPaletteLists();
202 $scope
.$watch('controls.addValue', function(fieldName
) {
204 if (!ctrl
.entity
.data
) {
205 ctrl
.entity
.data
= {};
207 ctrl
.entity
.data
[fieldName
] = '';
208 $scope
.controls
.addValue
= '';
215 })(angular
, CRM
.$, CRM
._
);