Merge remote-tracking branch 'upstream/4.4' into 4.4-master-2014-06-25-23-42-42
[civicrm-core.git] / js / angular-crmCaseType.js
1 (function(angular, $, _) {
2
3 var partialUrl = function(relPath) {
4 return CRM.resourceUrls['civicrm'] + '/partials/crmCaseType/' + relPath;
5 };
6
7 var crmCaseType = angular.module('crmCaseType', ['ngRoute', 'ui.utils']);
8
9 var newCaseTypeDefinitionTemplate = {
10 activityTypes: [
11 {name: 'Open Case', max_instances: 1 }
12 ],
13 activitySets: [
14 {
15 name: 'standard_timeline',
16 label: 'Standard Timeline',
17 timeline: '1', // Angular won't bind checkbox correctly with numeric 1
18 activityTypes: [
19 {name: 'Open Case', status: 'Completed' }
20 ]
21 }
22 ],
23 caseRoles: [
24 { name: 'Case Coordinator', creator: '1', manager: '1'}
25 ]
26 };
27
28 crmCaseType.config(['$routeProvider',
29 function($routeProvider) {
30 $routeProvider.when('/caseType', {
31 templateUrl: partialUrl('list.html'),
32 controller: 'CaseTypeListCtrl',
33 resolve: {
34 caseTypes: function($route, crmApi) {
35 return crmApi('CaseType', 'get', {});
36 }
37 }
38 });
39 $routeProvider.when('/caseType/:id', {
40 templateUrl: partialUrl('edit.html'),
41 controller: 'CaseTypeCtrl',
42 resolve: {
43 selectedCaseType: function($route, crmApi) {
44 if ( $route.current.params.id !== 'new') {
45 return crmApi('CaseType', 'getsingle', {id: $route.current.params.id});
46 }
47 else {
48 return { title: "", name: "", is_active: "1", weight: "1",
49 definition: _.extend({}, newCaseTypeDefinitionTemplate) };
50 }
51 }
52 }
53 });
54 }
55 ]);
56
57 // Add a new record by name.
58 // Ex: <crmAddName crm-options="['Alpha','Beta','Gamma']" crm-var="newItem" crm-on-add="callMyCreateFunction(newItem)" />
59 crmCaseType.directive('crmAddName', function() {
60 return {
61 restrict: 'AE',
62 template: '<input class="add-activity" type="hidden" />',
63 link: function(scope, element, attrs) {
64 /// Format list of options for select2's "data"
65 var getFormattedOptions = function() {
66 return {
67 results: _.map(scope[attrs.crmOptions], function(option){
68 return {id: option, text: option};
69 })
70 };
71 };
72
73 var input = $('input', element);
74
75 scope._resetSelection = function() {
76 $(input).select2('close');
77 $(input).select2('val', '');
78 scope[attrs.crmVar] = '';
79 };
80
81 $(input).select2({
82 data: getFormattedOptions,
83 createSearchChoice: function(term) {
84 return {id: term, text: term};
85 }
86 });
87 $(input).on('select2-selecting', function(e) {
88 scope[attrs.crmVar] = e.val;
89 scope.$evalAsync(attrs.crmOnAdd);
90 scope.$evalAsync('_resetSelection()');
91 e.preventDefault();
92 });
93
94 scope.$watch(attrs.crmOptions, function(value) {
95 $(input).select2('data', getFormattedOptions);
96 $(input).select2('val', '');
97 });
98 }
99 };
100 });
101
102 crmCaseType.controller('CaseTypeCtrl', function($scope, crmApi, selectedCaseType) {
103 $scope.partialUrl = partialUrl;
104
105 $scope.activityStatuses = CRM.crmCaseType.actStatuses;
106 $scope.activityTypes = CRM.crmCaseType.actTypes;
107 $scope.activityTypeNames = _.pluck(CRM.crmCaseType.actTypes, 'name');
108 $scope.relationshipTypeNames = _.pluck(CRM.crmCaseType.relTypes, 'label_b_a'); // label_b_a is CRM_Case_XMLProcessor::REL_TYPE_CNAME
109
110 $scope.workflows = {
111 'timeline': 'Timeline',
112 'sequence': 'Sequence'
113 };
114
115 $scope.caseType = selectedCaseType;
116 $scope.caseType.definition = $scope.caseType.definition || [];
117 $scope.caseType.definition.activityTypes = $scope.caseType.definition.activityTypes || [];
118 $scope.caseType.definition.activitySets = $scope.caseType.definition.activitySets || [];
119 $scope.caseType.definition.caseRoles = $scope.caseType.definition.caseRoles || [];
120 window.ct = $scope.caseType;
121
122 $scope.addActivitySet = function(workflow) {
123 var activitySet = {};
124 activitySet[workflow] = '1';
125 activitySet.activityTypes = [];
126
127 var offset = 1;
128 var names = _.pluck($scope.caseType.definition.activitySets, 'name');
129 while (_.contains(names, workflow + '_' + offset)) offset++;
130 activitySet.name = workflow + '_' + offset;
131 activitySet.label = (offset == 1 ) ? $scope.workflows[workflow] : ($scope.workflows[workflow] + ' #' + offset);
132
133 $scope.caseType.definition.activitySets.push(activitySet);
134 _.defer(function() {
135 $('.crmCaseType-acttab').tabs('refresh').tabs({active: -1});
136 });
137 };
138
139 /// Add a new activity entry to an activity-set
140 $scope.addActivity = function(activitySet, activityType) {
141 activitySet.activityTypes.push({
142 name: activityType
143 });
144 if (!_.contains($scope.activityTypeNames, activityType)) {
145 $scope.activityTypeNames.push(activityType);
146 }
147 };
148
149 /// Add a new top-level activity-type entry
150 $scope.addActivityType = function(activityType) {
151 var names = _.pluck($scope.caseType.definition.activityTypes, 'name');
152 if (!_.contains(names, activityType)) {
153 $scope.caseType.definition.activityTypes.push({
154 name: activityType
155 });
156
157 }
158 if (!_.contains($scope.activityTypeNames, activityType)) {
159 $scope.activityTypeNames.push(activityType);
160 }
161 };
162
163 /// Add a new role
164 $scope.addRole = function(roles, roleName) {
165 var names = _.pluck($scope.caseType.definition.caseRoles, 'name');
166 if (!_.contains(names, roleName)) {
167 roles.push({
168 name: roleName
169 });
170 }
171 if (!_.contains($scope.relationshipTypeNames, roleName)) {
172 $scope.relationshipTypeNames.push(roleName);
173 }
174 };
175
176 $scope.onManagerChange = function(managerRole) {
177 angular.forEach($scope.caseType.definition.caseRoles, function(caseRole) {
178 if (caseRole != managerRole) {
179 caseRole.manager = '0';
180 }
181 });
182 };
183
184 $scope.removeItem = function(array, item) {
185 var idx = _.indexOf(array, item);
186 if (idx != -1) {
187 array.splice(idx, 1);
188 }
189 };
190
191 $scope.isNewActivitySetAllowed = function(workflow) {
192 switch (workflow) {
193 case 'timeline':
194 return true;
195 case 'sequence':
196 return 0 == _.where($scope.caseType.definition.activitySets, {sequence: '1'}).length;
197 default:
198 if (console && console.log) console.log('Denied access to unrecognized workflow: (' + workflow + ')');
199 return false;
200 }
201 };
202
203 $scope.getWorkflowName = function(activitySet) {
204 var result = 'Unknown';
205 _.each($scope.workflows, function(value, key) {
206 if (activitySet[key]) result = value;
207 });
208 return result;
209 };
210
211 /**
212 * Determine which HTML partial to use for a particular
213 *
214 * @return string URL of the HTML partial
215 */
216 $scope.activityTableTemplate = function(activitySet) {
217 if (activitySet.timeline) {
218 return partialUrl('timelineTable.html');
219 } else if (activitySet.sequence) {
220 return partialUrl('sequenceTable.html');
221 } else {
222 return '';
223 }
224 };
225
226 $scope.dump = function() {
227 console.log($scope.caseType);
228 };
229
230 $scope.save = function() {
231 var result = crmApi('CaseType', 'create', $scope.caseType, true);
232 result.success(function(data) {
233 if (data.is_error == 0) {
234 $scope.caseType.id = data.id;
235 }
236 });
237 };
238
239 $scope.$watchCollection('caseType.definition.activitySets', function() {
240 _.defer(function() {
241 $('.crmCaseType-acttab').tabs('refresh');
242 });
243 });
244 });
245
246 crmCaseType.controller('CaseTypeListCtrl', function($scope, crmApi, caseTypes) {
247 $scope.caseTypes = caseTypes.values;
248 });
249
250 })(angular, CRM.$, CRM._);