Commit | Line | Data |
---|---|---|
25523059 CW |
1 | (function(angular, $, _) { |
2 | "use strict"; | |
3 | ||
4 | // Shared between router and searchMeta service | |
2c7e2f4b | 5 | var searchEntity, |
2c7e2f4b | 6 | undefined; |
25523059 CW |
7 | |
8 | // Declare module and route/controller/services | |
493f83d4 | 9 | angular.module('crmSearchAdmin', CRM.angRequires('crmSearchAdmin')) |
25523059 CW |
10 | |
11 | .config(function($routeProvider) { | |
475029f6 CW |
12 | $routeProvider.when('/list', { |
13 | controller: 'searchList', | |
493f83d4 | 14 | templateUrl: '~/crmSearchAdmin/searchList.html', |
475029f6 CW |
15 | resolve: { |
16 | // Load data for lists | |
17 | savedSearches: function(crmApi4) { | |
18 | return crmApi4('SavedSearch', 'get', { | |
7620b30a CW |
19 | select: [ |
20 | 'id', | |
21 | 'name', | |
22 | 'label', | |
23 | 'api_entity', | |
24 | 'form_values', | |
25 | 'GROUP_CONCAT(display.name ORDER BY display.id) AS display_name', | |
26 | 'GROUP_CONCAT(display.label ORDER BY display.id) AS display_label', | |
27 | 'GROUP_CONCAT(display.type:icon ORDER BY display.id) AS display_icon', | |
28 | 'GROUP_CONCAT(group.title) AS groups' | |
29 | ], | |
30 | join: [['SearchDisplay AS display'], ['Group AS group']], | |
475029f6 CW |
31 | where: [['api_entity', 'IS NOT NULL']], |
32 | groupBy: ['id'] | |
33 | }); | |
34 | } | |
35 | } | |
36 | }); | |
2894db84 CW |
37 | $routeProvider.when('/create/:entity', { |
38 | controller: 'searchCreate', | |
964ecb17 | 39 | template: '<crm-search-admin saved-search="$ctrl.savedSearch"></crm-search-admin>', |
2894db84 CW |
40 | }); |
41 | $routeProvider.when('/edit/:id', { | |
42 | controller: 'searchEdit', | |
964ecb17 | 43 | template: '<crm-search-admin saved-search="$ctrl.savedSearch"></crm-search-admin>', |
2c7e2f4b | 44 | resolve: { |
2894db84 CW |
45 | // Load saved search |
46 | savedSearch: function($route, crmApi4) { | |
47 | var params = $route.current.params; | |
48 | return crmApi4('SavedSearch', 'get', { | |
49 | where: [['id', '=', params.id]], | |
50 | chain: { | |
44402a2e | 51 | groups: ['Group', 'get', {where: [['saved_search_id', '=', '$id']]}], |
2894db84 CW |
52 | displays: ['SearchDisplay', 'get', {where: [['saved_search_id', '=', '$id']]}] |
53 | } | |
54 | }, 0); | |
2c7e2f4b CW |
55 | } |
56 | } | |
25523059 CW |
57 | }); |
58 | }) | |
59 | ||
2894db84 CW |
60 | // Controller for creating a new search |
61 | .controller('searchCreate', function($scope, $routeParams, $location) { | |
62 | searchEntity = $routeParams.entity; | |
2c7e2f4b | 63 | $scope.$ctrl = this; |
2894db84 CW |
64 | this.savedSearch = { |
65 | api_entity: searchEntity, | |
66 | }; | |
25523059 | 67 | // Changing entity will refresh the angular page |
2894db84 | 68 | $scope.$watch('$ctrl.savedSearch.api_entity', function(newEntity, oldEntity) { |
25523059 | 69 | if (newEntity && oldEntity && newEntity !== oldEntity) { |
2c7e2f4b | 70 | $location.url('/create/' + newEntity); |
25523059 CW |
71 | } |
72 | }); | |
73 | }) | |
74 | ||
2894db84 CW |
75 | // Controller for editing a SavedSearch |
76 | .controller('searchEdit', function($scope, savedSearch) { | |
77 | searchEntity = savedSearch.api_entity; | |
78 | this.savedSearch = savedSearch; | |
79 | $scope.$ctrl = this; | |
80 | }) | |
81 | ||
25523059 CW |
82 | .factory('searchMeta', function() { |
83 | function getEntity(entityName) { | |
84 | if (entityName) { | |
25523059 CW |
85 | return _.find(CRM.vars.search.schema, {name: entityName}); |
86 | } | |
87 | } | |
c419e6ed CW |
88 | function getField(fieldName, entityName) { |
89 | var dotSplit = fieldName.split('.'), | |
25523059 | 90 | joinEntity = dotSplit.length > 1 ? dotSplit[0] : null, |
f9cf8797 CW |
91 | name = _.last(dotSplit).split(':')[0], |
92 | field; | |
27bed3cb CW |
93 | // Custom fields contain a dot in their fieldname |
94 | // If 3 segments, the first is the joinEntity and the last 2 are the custom field | |
95 | if (dotSplit.length === 3) { | |
c419e6ed | 96 | name = dotSplit[1] + '.' + name; |
27bed3cb CW |
97 | } |
98 | // If 2 segments, it's ambiguous whether this is a custom field or joined field. Search the main entity first. | |
99 | if (dotSplit.length === 2) { | |
f9cf8797 | 100 | field = _.find(getEntity(entityName).fields, {name: dotSplit[0] + '.' + name}); |
27bed3cb | 101 | if (field) { |
f9cf8797 | 102 | field.entity = entityName; |
27bed3cb CW |
103 | return field; |
104 | } | |
105 | } | |
25523059 CW |
106 | if (joinEntity) { |
107 | entityName = _.find(CRM.vars.search.links[entityName], {alias: joinEntity}).entity; | |
108 | } | |
f9cf8797 CW |
109 | field = _.find(getEntity(entityName).fields, {name: name}); |
110 | if (field) { | |
111 | field.entity = entityName; | |
112 | return field; | |
113 | } | |
25523059 CW |
114 | } |
115 | return { | |
116 | getEntity: getEntity, | |
117 | getField: getField, | |
118 | parseExpr: function(expr) { | |
f99d41d2 | 119 | var result = {fn: null, modifier: ''}, |
25523059 CW |
120 | fieldName = expr, |
121 | bracketPos = expr.indexOf('('); | |
122 | if (bracketPos >= 0) { | |
f99d41d2 CW |
123 | var parsed = expr.substr(bracketPos).match(/[ ]?([A-Z]+[ ]+)?([\w.:]+)/); |
124 | fieldName = parsed[2]; | |
493f83d4 | 125 | result.fn = _.find(CRM.crmSearchAdmin.functions, {name: expr.substring(0, bracketPos)}); |
f99d41d2 | 126 | result.modifier = _.trim(parsed[1]); |
25523059 | 127 | } |
c419e6ed CW |
128 | result.field = expr ? getField(fieldName, searchEntity) : undefined; |
129 | if (result.field) { | |
130 | var split = fieldName.split(':'), | |
131 | prefixPos = split[0].lastIndexOf(result.field.name); | |
132 | result.path = split[0]; | |
133 | result.prefix = prefixPos > 0 ? result.path.substring(0, prefixPos) : ''; | |
134 | result.suffix = !split[1] ? '' : ':' + split[1]; | |
135 | } | |
25523059 | 136 | return result; |
4b01551f CW |
137 | }, |
138 | // Find all possible search columns that could serve as contact_id for a smart group | |
139 | getSmartGroupColumns: function(api_entity, api_params) { | |
140 | var joins = _.pluck((api_params.join || []), 0), | |
141 | entityCount = {}; | |
142 | return _.transform([api_entity].concat(joins), function(columns, joinExpr) { | |
143 | var joinName = joinExpr.split(' AS '), | |
144 | entityName = joinName[0], | |
145 | entity = getEntity(entityName), | |
146 | prefix = joinName[1] ? joinName[1] + '.' : ''; | |
147 | _.each(entity.fields, function(field) { | |
148 | if ((entityName === 'Contact' && field.name === 'id') || field.fk_entity === 'Contact') { | |
149 | columns.push({ | |
150 | id: prefix + field.name, | |
493f83d4 | 151 | text: entity.title_plural + (entityCount[entityName] ? ' ' + entityCount[entityName] : '') + ': ' + field.label, |
4b01551f CW |
152 | icon: entity.icon |
153 | }); | |
154 | } | |
155 | }); | |
156 | entityCount[entityName] = 1 + (entityCount[entityName] || 1); | |
157 | }); | |
25523059 CW |
158 | } |
159 | }; | |
25523059 CW |
160 | }); |
161 | ||
162 | })(angular, CRM.$, CRM._); |