CRM-15578 - crmAttachments - Convert include+ctrl to a directive
[civicrm-core.git] / js / angular-crmAttachment.js
CommitLineData
f44610a1
TO
1/// crmFile: Manage file attachments
2(function (angular, $, _) {
3 var partialUrl = function (relPath) {
4 return CRM.resourceUrls['civicrm'] + '/partials/crmAttachment/' + relPath;
5 };
6
7 angular.module('crmAttachment', ['angularFileUpload']);
8
9 // crmAttachment manages the list of files which are attached to a given entity
10 angular.module('crmAttachment').factory('CrmAttachments', function (crmApi, crmStatus, FileUploader, $q) {
11 var _target;
12
13 // @param target an Object(entity_table:'',entity_id:'') or function which generates an object
14 function CrmAttachments(target) {
15 _target = target;
16 var crmAttachments = this;
17 this.files = [];
18 this.uploader = new FileUploader({
19 url: CRM.url('civicrm/ajax/attachment'),
20 onAfterAddingFile: function onAfterAddingFile(item) {
21 item.crmData = {
22 description: ''
23 };
24 },
25 onSuccessItem: function onSuccessItem(item, response, status, headers) {
26 crmAttachments.files.push(response.file.values[response.file.id]);
27 crmAttachments.uploader.removeFromQueue(item);
28 },
29 onErrorItem: function onErrorItem(item, response, status, headers) {
30 var msg = (response && response.file && response.file.error_message) ? response.file.error_message : ts('Unknown error');
31 CRM.alert(item.file.name + ' - ' + msg, ts('Attachment failed'));
32 crmAttachments.uploader.removeFromQueue(item);
33 }
34 });
35 }
36
37 angular.extend(CrmAttachments.prototype, {
38 // @return Object(entity_table:'',entity_id:'')
39 getTarget: function () {
40 return (angular.isFunction(_target) ? _target() : _target);
41 },
42 // @return Promise<Attachment>
43 load: function load() {
44 var target = this.getTarget();
45 var Attachment = this;
46
47 if (target.entity_id) {
48 var params = {
49 entity_table: target.entity_table,
50 entity_id: target.entity_id
51 };
52 return crmApi('Attachment', 'get', params).then(function (apiResult) {
53 Attachment.files = _.values(apiResult.values);
54 return Attachment;
55 });
56 }
57 else {
58 var dfr = $q.defer();
59 Attachment.files = [];
60 dfr.resolve(Attachment);
61 return dfr.promise;
62 }
63 },
64 // @return Promise
65 save: function save() {
66 var crmAttachments = this;
67 var target = this.getTarget();
68 if (!target.entity_table || !target.entity_id) {
69 throw "Cannot save attachments: unknown entity_table or entity_id";
70 }
71
72 var params = _.extend({}, target);
73 params.values = crmAttachments.files;
74 return crmApi('Attachment', 'replace', params)
75 .then(function () {
76 var dfr = $q.defer();
77
78 var newItems = crmAttachments.uploader.getNotUploadedItems();
79 if (newItems.length > 0) {
80 _.each(newItems, function (item) {
81 item.formData = [_.extend({}, target, item.crmData)];
82 });
83 crmAttachments.uploader.onCompleteAll = function onCompleteAll() {
84 delete crmAttachments.uploader.onCompleteAll;
85 dfr.resolve(crmAttachments);
86 };
87 crmAttachments.uploader.uploadAll();
88 }
89 else {
90 dfr.resolve(crmAttachments);
91 }
92
93 return dfr.promise;
94 });
95 },
96 // @param Object file APIv3 attachment record (e.g. id, entity_table, entity_id, description)
97 deleteFile: function deleteFile(file) {
98 var crmAttachments = this;
99
100 var idx = _.indexOf(this.files, file);
101 if (idx != -1) {
102 this.files.splice(idx, 1);
103 }
104
105 if (file.id) {
106 var p = crmApi('Attachment', 'delete', {id: file.id}).then(
107 function () { // success
108 },
109 function (response) { // error; restore the file
110 var msg = angular.isObject(response) ? response.error_message : '';
111 CRM.alert(msg, ts('Deletion failed'));
112 crmAttachments.files.push(file);
113 }
114 );
115 return crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, p);
116 }
117 }
118 });
119
120 return CrmAttachments;
121 });
122
123 // example:
ab0a4aec
TO
124 // $scope.myAttachments = new CrmAttachments({entity_table: 'civicrm_mailing', entity_id: 123});
125 // <div crm-attachments="myAttachments"/>
126 angular.module('crmAttachment').directive('crmAttachments', function ($parse, $timeout) {
127 return {
128 scope: {
129 crmAttachments: '@'
130 },
131 template: '<div ng-if="ready" ng-include="inclUrl"></div>',
132 link: function (scope, elm, attr) {
133 var model = $parse(attr.crmAttachments);
134 scope.att = model(scope.$parent);
135 scope.ts = CRM.ts(null);
136 scope.inclUrl = partialUrl('attachments.html');
137
138 // delay rendering of child tree until after model has been populated
139 scope.ready = true;
140 }
f44610a1
TO
141 };
142 });
143
144})(angular, CRM.$, CRM._);