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();
15 $scope
.fieldList
= [];
16 $scope
.blockList
= [];
17 $scope
.blockTitles
= [];
18 $scope
.elementList
= [];
19 $scope
.elementTitles
= [];
21 function getEntityType() {
22 return ctrl
.entity
.type
=== 'Contact' ? ctrl
.entity
.data
.contact_type
: ctrl
.entity
.type
;
25 $scope
.getMeta = function() {
26 return afGui
.meta
.entities
[getEntityType()];
29 $scope
.getField
= afGui
.getField
;
31 $scope
.valuesFields = function() {
32 var fields
= _
.transform($scope
.getMeta().fields
, function(fields
, field
) {
33 fields
.push({id
: field
.name
, text
: field
.label
, disabled
: $scope
.fieldInUse(field
.name
)});
35 return {results
: fields
};
38 $scope
.removeValue = function(entity
, fieldName
) {
39 delete entity
.data
[fieldName
];
42 function buildPaletteLists() {
43 var search
= $scope
.controls
.fieldSearch
? $scope
.controls
.fieldSearch
.toLowerCase() : null;
44 buildFieldList(search
);
45 buildBlockList(search
);
46 buildElementList(search
);
49 function buildFieldList(search
) {
50 $scope
.fieldList
.length
= 0;
51 $scope
.fieldList
.push({
52 entityName
: ctrl
.entity
.name
,
53 entityType
: getEntityType(),
54 label
: ts('%1 Fields', {1: $scope
.getMeta().label
}),
55 fields
: filterFields($scope
.getMeta().fields
)
58 _
.each(afGui
.meta
.entities
, function(entity
, entityName
) {
59 if (check(ctrl
.editor
.layout
['#children'], {'af-join': entityName
})) {
60 $scope
.fieldList
.push({
61 entityName
: ctrl
.entity
.name
+ '-join-' + entityName
,
62 entityType
: entityName
,
63 label
: ts('%1 Fields', {1: entity
.label
}),
64 fields
: filterFields(entity
.fields
)
69 function filterFields(fields
) {
70 return _
.transform(fields
, function(fieldList
, field
) {
71 if (!search
|| _
.contains(field
.name
, search
) || _
.contains(field
.label
.toLowerCase(), search
)) {
81 function buildBlockList(search
) {
82 $scope
.blockList
.length
= 0;
83 $scope
.blockTitles
.length
= 0;
84 _
.each(afGui
.meta
.blocks
, function(block
, directive
) {
85 if ((!search
|| _
.contains(directive
, search
) || _
.contains(block
.name
.toLowerCase(), search
) || _
.contains(block
.title
.toLowerCase(), search
)) &&
86 (block
.block
=== '*' || block
.block
=== ctrl
.entity
.type
|| (ctrl
.entity
.type
=== 'Contact' && block
.block
=== ctrl
.entity
.data
.contact_type
))
88 var item
= {"#tag": block
.join
? "div" : directive
};
90 item
['af-join'] = block
.join
;
91 item
['#children'] = [{"#tag": directive
}];
94 item
['af-repeat'] = ts('Add');
96 if (typeof block
.repeat
=== 'number') {
97 item
.max
= '' + block
.repeat
;
100 $scope
.blockList
.push(item
);
101 $scope
.blockTitles
.push(block
.title
);
106 function buildElementList(search
) {
107 $scope
.elementList
.length
= 0;
108 $scope
.elementTitles
.length
= 0;
109 _
.each(afGui
.meta
.elements
, function(element
, name
) {
110 if (!search
|| _
.contains(name
, search
) || _
.contains(element
.title
.toLowerCase(), search
)) {
111 var node
= _
.cloneDeep(element
.element
);
112 if (name
=== 'fieldset') {
113 node
['af-fieldset'] = ctrl
.entity
.name
;
115 $scope
.elementList
.push(node
);
116 $scope
.elementTitles
.push(name
=== 'fieldset' ? ts('Fieldset for %1', {1: ctrl
.entity
.label
}) : element
.title
);
121 $scope
.clearSearch = function() {
122 $scope
.controls
.fieldSearch
= '';
125 // This gets called from jquery-ui so we have to manually apply changes to scope
126 $scope
.buildPaletteLists = function() {
127 $timeout(function() {
128 $scope
.$apply(function() {
134 // Checks if a field is on the form or set as a value
135 $scope
.fieldInUse = function(fieldName
) {
136 var data
= ctrl
.entity
.data
|| {};
137 if (fieldName
in data
) {
140 return check(ctrl
.editor
.layout
['#children'], {'#tag': 'af-field', name
: fieldName
});
143 $scope
.blockInUse = function(block
) {
144 if (block
['af-join']) {
145 return check(ctrl
.editor
.layout
['#children'], {'af-join': block
['af-join']});
147 var fieldsInBlock
= _
.pluck(afGui
.findRecursive(afGui
.meta
.blocks
[block
['#tag']].layout
, {'#tag': 'af-field'}), 'name');
148 return check(ctrl
.editor
.layout
['#children'], function(item
) {
149 return item
['#tag'] === 'af-field' && _
.includes(fieldsInBlock
, item
.name
);
153 // Check for a matching item for this entity
154 // Recursively checks the form layout, including block directives
155 function check(group
, criteria
, found
) {
159 if (_
.find(group
, criteria
)) {
163 _
.each(group
, function(item
) {
167 if (_
.isPlainObject(item
)) {
168 // Recurse through everything but skip fieldsets for other entities
169 if ((!item
['af-fieldset'] || (item
['af-fieldset'] === ctrl
.entity
.name
)) && item
['#children']) {
170 check(item
['#children'], criteria
, found
);
172 // Recurse into block directives
173 else if (item
['#tag'] && item
['#tag'] in afGui
.meta
.blocks
) {
174 check(afGui
.meta
.blocks
[item
['#tag']].layout
, criteria
, found
);
181 $scope
.$watch('controls.addValue', function(fieldName
) {
183 if (!ctrl
.entity
.data
) {
184 ctrl
.entity
.data
= {};
186 ctrl
.entity
.data
[fieldName
] = '';
187 $scope
.controls
.addValue
= '';
191 $scope
.$watch('controls.fieldSearch', buildPaletteLists
);
195 })(angular
, CRM
.$, CRM
._
);