CRM-15855 - crmMailing - Fix autosave for attachments
[civicrm-core.git] / js / angular-crm-util.js
CommitLineData
60ebf0a5
TO
1/// crmUi: Sundry UI helpers
2(function (angular, $, _) {
3 angular.module('crmUtil', []);
4
a8e65974
TO
5 angular.module('crmUtil').factory('crmApi', function($q) {
6 return function(entity, action, params, message) {
7 // JSON serialization in CRM.api3 is not aware of Angular metadata like $$hash, so use angular.toJson()
8 var deferred = $q.defer();
9 var p;
10 if (_.isObject(entity)) {
f91e4af5
TO
11 // eval content is locally generated.
12 /*jshint -W061 */
a8e65974
TO
13 p = CRM.api3(eval('('+angular.toJson(entity)+')'), message);
14 } else {
f91e4af5
TO
15 // eval content is locally generated.
16 /*jshint -W061 */
a8e65974
TO
17 p = CRM.api3(entity, action, eval('('+angular.toJson(params)+')'), message);
18 }
19 // CRM.api3 returns a promise, but the promise doesn't really represent errors as errors, so we
20 // convert them
21 p.then(
22 function(result) {
23 if (result.is_error) {
24 deferred.reject(result);
25 } else {
26 deferred.resolve(result);
27 }
28 },
29 function(error) {
30 deferred.reject(error);
31 }
32 );
33 return deferred.promise;
34 };
35 });
36
bdd3f781
TO
37 // usage:
38 // var block = $scope.block = crmBlocker();
39 // $scope.save = function() { return block(crmApi('MyEntity','create',...)); };
40 // <button ng-click="save()" ng-disabled="block.check()">Do something</button>
41 angular.module('crmUtil').factory('crmBlocker', function() {
42 return function() {
43 var blocks = 0;
44 var result = function(promise) {
45 blocks++;
46 promise.finally(function() {
47 blocks--;
48 });
49 };
50 result.check = function() {
51 return blocks > 0;
52 };
53 return result;
54 };
55 });
56
a8e65974
TO
57 angular.module('crmUtil').factory('crmLegacy', function() {
58 return CRM;
59 });
60
226ef186
TO
61 // example: scope.$watch('foo', crmLog.wrap(function(newValue, oldValue){ ... }));
62 angular.module('crmUtil').factory('crmLog', function(){
63 var level = 0;
64 var write = console.log;
65 function indent() {
66 var s = '>';
67 for (var i = 0; i < level; i++) s = s + ' ';
68 return s;
69 }
70 var crmLog = {
71 log: function(msg, vars) {
72 write(indent() + msg, vars);
73 },
74 wrap: function(label, f) {
75 return function(){
76 level++;
77 crmLog.log(label + ": start", arguments);
78 var r;
79 try {
80 r = f.apply(this, arguments);
81 } finally {
82 crmLog.log(label + ": end");
83 level--;
84 }
85 return r;
f2bad133 86 };
226ef186 87 }
f286acec 88 };
226ef186 89 return crmLog;
f286acec
TO
90 });
91
a8e65974
TO
92 angular.module('crmUtil').factory('crmNavigator', ['$window', function($window) {
93 return {
94 redirect: function(path) {
95 $window.location.href = path;
96 }
97 };
98 }]);
99
8717390f
TO
100 angular.module('crmUtil').factory('crmNow', function($q){
101 // FIXME: surely there's already some helper which can do this in one line?
102 // @return string "YYYY-MM-DD hh:mm:ss"
103 return function crmNow() {
104 var currentdate = new Date();
105 var yyyy = currentdate.getFullYear();
106 var mm = currentdate.getMonth() + 1;
107 mm = mm < 10 ? '0' + mm : mm;
108 var dd = currentdate.getDate();
109 dd = dd < 10 ? '0' + dd : dd;
110 var hh = currentdate.getHours();
111 hh = hh < 10 ? '0' + hh : hh;
112 var min = currentdate.getMinutes();
113 min = min < 10 ? '0' + min : min;
114 var sec = currentdate.getSeconds();
115 sec = sec < 10 ? '0' + sec : sec;
116 return yyyy + "-" + mm + "-" + dd + " " + hh + ":" + min + ":" + sec;
117 };
118 });
119
226ef186
TO
120 // Adapter for CRM.status which supports Angular promises (instead of jQuery promises)
121 // example: crmStatus('Saving', crmApi(...)).then(function(result){...})
122 angular.module('crmUtil').factory('crmStatus', function($q){
123 return function(options, aPromise){
a66571ab
TO
124 if (aPromise) {
125 return CRM.toAPromise($q, CRM.status(options, CRM.toJqPromise(aPromise)));
126 } else {
127 return CRM.toAPromise($q, CRM.status(options));
128 }
226ef186
TO
129 };
130 });
131
60ebf0a5
TO
132 // crmWatcher allows one to setup event listeners and temporarily suspend
133 // them en masse.
134 //
135 // example:
136 // angular.controller(... function($scope, crmWatcher){
137 // var watcher = crmWatcher();
138 // function myfunc() {
139 // watcher.suspend('foo', function(){
140 // ...do stuff...
141 // });
142 // }
143 // watcher.setup('foo', function(){
144 // return [
145 // $scope.$watch('foo', myfunc),
146 // $scope.$watch('bar', myfunc),
147 // $scope.$watch('whiz', otherfunc)
148 // ];
149 // });
150 // });
151 angular.module('crmUtil').factory('crmWatcher', function(){
152 return function() {
153 var unwatches = {}, watchFactories = {}, suspends = {};
154
155 // Specify the list of watches
156 this.setup = function(name, newWatchFactory) {
157 watchFactories[name] = newWatchFactory;
158 unwatches[name] = watchFactories[name]();
159 suspends[name] = 0;
160 return this;
161 };
162
163 // Temporarily disable watches and run some logic
164 this.suspend = function(name, f) {
165 suspends[name]++;
166 this.teardown(name);
167 var r;
168 try {
169 r = f.apply(this, []);
170 } finally {
171 if (suspends[name] === 1) {
172 unwatches[name] = watchFactories[name]();
173 if (!angular.isArray(unwatches[name])) {
174 unwatches[name] = [unwatches[name]];
175 }
176 }
177 suspends[name]--;
178 }
179 return r;
180 };
181
182 this.teardown = function(name) {
183 if (!unwatches[name]) return;
184 _.each(unwatches[name], function(unwatch){
185 unwatch();
186 });
187 delete unwatches[name];
188 };
189
190 return this;
f2bad133 191 };
60ebf0a5
TO
192 });
193
60ebf0a5 194})(angular, CRM.$, CRM._);