Merge pull request #19046 from dwoods-encircle/Resource-URL-helptext-update
[civicrm-core.git] / ang / exportui / exportui.js
1 (function(angular, $, _) {
2 angular.module('exportui', CRM.angRequires('exportui'));
3
4 angular.module('exportui', CRM.angular.modules)
5
6 .controller('ExportUiCtrl', function($scope, $timeout, crmApi, dialogService) {
7 var ts = $scope.ts = CRM.ts('exportui'),
8 // Which relationships we've already looked up for the preview
9 relations = [];
10
11 $scope.option_list = CRM.vars.exportUi.option_list;
12 $scope.contact_types = CRM.vars.exportUi.contact_types;
13 $scope.location_type_id = [{id: '', text: ts('Primary')}].concat(CRM.vars.exportUi.location_type_id);
14 // Map of all fields keyed by name
15 $scope.fields = _.transform(CRM.vars.exportUi.fields, function(result, category) {
16 _.each(category.children, function(field) {
17 result[field.id] = field;
18 });
19 }, {});
20 $scope.data = {
21 preview: CRM.vars.exportUi.preview_data,
22 contact_type: '',
23 columns: []
24 };
25 // For the "add new field" dropdown
26 $scope.new = {col: ''};
27 var contactTypes = _.transform($scope.contact_types, function(result, type) {
28 result.push(type.id);
29 _.each(type.children || [], function(subType) {
30 result.push(subType.id);
31 });
32 });
33 var cids = _.filter(_.map(CRM.vars.exportUi.preview_data, 'id'));
34
35 // Get fields for performing the export or saving the field mapping
36 function getSelectedColumns() {
37 var map = [];
38 _.each($scope.data.columns, function(col, no) {
39 // Make a copy of col without the extra angular props
40 var item = JSON.parse(angular.toJson(col));
41 delete item.select;
42 delete item.mapping_id;
43 item.contact_type = $scope.data.contact_type || 'Contact';
44 item.column_number = no;
45 map.push(item);
46 });
47 return map;
48 }
49
50 // Load a saved field mapping
51 function loadFieldMap(map) {
52 $scope.data.columns = [];
53 var mapContactTypes = [];
54 _.each(map, function(col) {
55 if (_.contains(contactTypes, col.contact_type)) {
56 mapContactTypes.push(col.contact_type);
57 }
58 if (col.relationship_type_id && col.relationship_direction) {
59 col.select = '' + col.relationship_type_id + '_' + col.relationship_direction;
60 } else {
61 col.select = col.name;
62 }
63 $scope.data.columns.push(col);
64 });
65 // If all the fields are for the same contact type, set it form-wide
66 if (!$scope.data.contact_type && _.unique(mapContactTypes).length === 1) {
67 $scope.data.contact_type = mapContactTypes[0];
68 }
69 }
70
71 // Return fields relevant to a contact type
72 // Filter out non-contact fields (for relationship selectors)
73 function filterFields(contactType, onlyContact) {
74 return _.transform(CRM.vars.exportUi.fields, function(result, cat) {
75 if (!cat.is_contact && onlyContact) {
76 return;
77 }
78 var fields = _.filter(cat.children, function(field) {
79 return !field.contact_type || !contactType || _.contains(field.contact_type, contactType);
80 });
81 if (fields.length) {
82 result.push({
83 id: cat.id,
84 text: cat.text,
85 children: fields
86 });
87 }
88 });
89 }
90
91 $scope.getFields = function() {
92 return {results: filterFields($scope.data.contact_type)};
93 };
94
95 $scope.getRelatedFields = function(contact_type) {
96 return function() {
97 return {results: filterFields(contact_type, true)};
98 };
99 };
100
101 $scope.showPreview = function(row, field) {
102 var key = field.name;
103 if (field.relationship_type_id && field.relationship_direction) {
104 fetchRelations(field);
105 key = '' + field.relationship_type_id + '_' + field.relationship_direction + '_' + key;
106 }
107 if (field.location_type_id) {
108 key += '_' + field.location_type_id + (field.phone_type_id ? '_' + field.phone_type_id : '');
109 }
110 return field.name ? row[key] : '';
111 };
112
113 function fetchRelations(field) {
114 if (cids.length && !relations[field.relationship_type_id + field.relationship_direction]) {
115 relations[field.relationship_type_id + field.relationship_direction] = true;
116 var a = field.relationship_direction[0],
117 b = field.relationship_direction[2],
118 params = {
119 relationship_type_id: field.relationship_type_id,
120 filters: {is_current: 1},
121 "api.Contact.getsingle": {id: '$value.contact_id_' + b}
122 };
123 params['contact_' + a] = {'IN': cids};
124 (function (field, params) {
125 crmApi('Relationship', 'get', params).then(function (data) {
126 _.each(data.values, function (rel) {
127 var row = cids.indexOf(rel['contact_id_' + a]);
128 if (row > -1) {
129 _.each(rel["api.Contact.getsingle"], function (item, key) {
130 $scope.data.preview[row][field.relationship_type_id + '_' + field.relationship_direction + '_' + key] = item;
131 });
132 }
133 });
134 });
135 })(field, params);
136 }
137 }
138
139 $scope.saveMappingDialog = function() {
140 var options = CRM.utils.adjustDialogDefaults({
141 width: '40%',
142 height: 300,
143 autoOpen: false,
144 title: ts('Save Fields')
145 });
146 var mappingNames = _.transform(CRM.vars.exportUi.mapping_names, function(result, n, key) {
147 result[key] = n.toLowerCase();
148 });
149 var model = {
150 ts: ts,
151 saving: false,
152 overwrite: CRM.vars.exportUi.mapping_id ? '1' : '0',
153 mapping_id: CRM.vars.exportUi.mapping_id,
154 mapping_type_id: CRM.vars.exportUi.mapping_type_id,
155 mapping_names: CRM.vars.exportUi.mapping_names,
156 new_name: CRM.vars.exportUi.mapping_id ? CRM.vars.exportUi.mapping_names[CRM.vars.exportUi.mapping_id] : '',
157 description: CRM.vars.exportUi.mapping_description,
158 nameIsUnique: function() {
159 return !_.contains(mappingNames, this.new_name.toLowerCase()) || (this.overwrite === '1' && this.new_name.toLowerCase() === this.mapping_names[this.mapping_id].toLowerCase());
160 },
161 saveMapping: function() {
162 this.saving = true;
163 var mapping = {
164 id: this.overwrite === '1' ? this.mapping_id : null,
165 mapping_type_id: this.mapping_type_id,
166 name: this.new_name,
167 description: this.description,
168 sequential: 1
169 },
170 mappingFields = getSelectedColumns();
171 if (!mapping.id) {
172 _.each(mappingFields, function(field) {
173 delete field.id;
174 });
175 }
176 mapping['api.MappingField.replace'] = {values: mappingFields};
177 crmApi('Mapping', 'create', mapping).then(function(result) {
178 CRM.vars.exportUi.mapping_id = result.id;
179 CRM.vars.exportUi.mapping_description = mapping.description;
180 CRM.vars.exportUi.mapping_names[result.id] = mapping.name;
181 // Call loadFieldMap to update field ids in $scope.data.columns
182 loadFieldMap(result.values[0]['api.MappingField.replace'].values);
183 dialogService.close('exportSaveMapping');
184 });
185 }
186 };
187 dialogService.open('exportSaveMapping', '~/exportui/exportSaveMapping.html', model, options);
188 };
189
190 // Load saved mapping
191 if ($('input[name=export_field_map]').val()) {
192 loadFieldMap(JSON.parse($('input[name=export_field_map]').val()));
193 }
194
195 // Add new col
196 $scope.$watch('new.col', function(val) {
197 var field = val;
198 $timeout(function() {
199 if (field) {
200 $scope.data.columns.push({
201 select: field,
202 name: '',
203 location_type_id: null,
204 phone_type_id: null,
205 website_type_id: null,
206 im_provider_id: null,
207 relationship_type_id: null,
208 relationship_direction: null
209 });
210 $scope.new.col = '';
211 }
212 });
213 });
214
215 // When adding/removing columns
216 $scope.$watch('data.columns', function(values) {
217 _.each(values, function(col, index) {
218 // Remove empty values
219 if (!col.select) {
220 $scope.data.columns.splice(index, 1);
221 } else {
222 // Format item
223 var selection = $scope.fields[col.select];
224 if (selection.relationship_type_id) {
225 col.relationship_type_id = selection.relationship_type_id;
226 col.relationship_direction = col.select.slice(col.select.indexOf('_')+1);
227 } else {
228 col.name = col.select;
229 col.relationship_direction = col.relationship_type_id = null;
230 }
231 var field = col.name ? $scope.fields[col.name] : {};
232 col.location_type_id = field.has_location ? col.location_type_id || '' : null;
233 _.each($scope.option_list, function(options, list) {
234 col[list] = (col.location_type_id || !field.has_location) && field.option_list === list ? col[list] || options[0].id : null;
235 });
236 }
237 });
238 // Store data in a quickform hidden field
239 var selectedColumns = getSelectedColumns();
240 $('input[name=export_field_map]').val(JSON.stringify(selectedColumns));
241
242 // Hide submit button when no fields selected
243 $('.crm-button_qf_Map_next').toggle(!!selectedColumns.length);
244 }, true);
245 });
246
247 })(angular, CRM.$, CRM._);