1 /// crmFile: Manage file attachments
2 (function (angular
, $, _
) {
3 var partialUrl = function (relPath
) {
4 return CRM
.resourceUrls
['civicrm'] + '/partials/crmAttachment/' + relPath
;
7 angular
.module('crmAttachment', ['angularFileUpload']);
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 // @param target an Object(entity_table:'',entity_id:'') or function which generates an object
12 function CrmAttachments(target
) {
13 var crmAttachments
= this;
14 this._target
= target
;
16 this.uploader
= new FileUploader({
17 url
: CRM
.url('civicrm/ajax/attachment'),
18 onAfterAddingFile
: function onAfterAddingFile(item
) {
23 onSuccessItem
: function onSuccessItem(item
, response
, status
, headers
) {
24 crmAttachments
.files
.push(response
.file
.values
[response
.file
.id
]);
25 crmAttachments
.uploader
.removeFromQueue(item
);
27 onErrorItem
: function onErrorItem(item
, response
, status
, headers
) {
28 var msg
= (response
&& response
.file
&& response
.file
.error_message
) ? response
.file
.error_message
: ts('Unknown error');
29 CRM
.alert(item
.file
.name
+ ' - ' + msg
, ts('Attachment failed'));
30 crmAttachments
.uploader
.removeFromQueue(item
);
35 angular
.extend(CrmAttachments
.prototype, {
36 // @return Object(entity_table:'',entity_id:'')
37 getTarget: function () {
38 return (angular
.isFunction(this._target
) ? this._target() : this._target
);
40 // @return Promise<Attachment>
41 load
: function load() {
42 var target
= this.getTarget();
43 var Attachment
= this;
45 if (target
.entity_id
) {
47 entity_table
: target
.entity_table
,
48 entity_id
: target
.entity_id
50 return crmApi('Attachment', 'get', params
).then(function (apiResult
) {
51 Attachment
.files
= _
.values(apiResult
.values
);
57 Attachment
.files
= [];
58 dfr
.resolve(Attachment
);
63 save
: function save() {
64 var crmAttachments
= this;
65 var target
= this.getTarget();
66 if (!target
.entity_table
|| !target
.entity_id
) {
67 throw "Cannot save attachments: unknown entity_table or entity_id";
70 var params
= _
.extend({}, target
);
71 params
.values
= crmAttachments
.files
;
72 return crmApi('Attachment', 'replace', params
)
76 var newItems
= crmAttachments
.uploader
.getNotUploadedItems();
77 if (newItems
.length
> 0) {
78 _
.each(newItems
, function (item
) {
79 item
.formData
= [_
.extend({}, target
, item
.crmData
)];
81 crmAttachments
.uploader
.onCompleteAll
= function onCompleteAll() {
82 delete crmAttachments
.uploader
.onCompleteAll
;
83 dfr
.resolve(crmAttachments
);
85 crmAttachments
.uploader
.uploadAll();
88 dfr
.resolve(crmAttachments
);
94 // @param Object file APIv3 attachment record (e.g. id, entity_table, entity_id, description)
95 deleteFile
: function deleteFile(file
) {
96 var crmAttachments
= this;
98 var idx
= _
.indexOf(this.files
, file
);
100 this.files
.splice(idx
, 1);
104 var p
= crmApi('Attachment', 'delete', {id
: file
.id
}).then(
105 function () { // success
107 function (response
) { // error; restore the file
108 var msg
= angular
.isObject(response
) ? response
.error_message
: '';
109 CRM
.alert(msg
, ts('Deletion failed'));
110 crmAttachments
.files
.push(file
);
113 return crmStatus({start
: ts('Deleting...'), success
: ts('Deleted')}, p
);
118 return CrmAttachments
;
122 // $scope.myAttachments = new CrmAttachments({entity_table: 'civicrm_mailing', entity_id: 123});
123 // <div crm-attachments="myAttachments"/>
124 angular
.module('crmAttachment').directive('crmAttachments', function ($parse
, $timeout
) {
129 template
: '<div ng-if="ready" ng-include="inclUrl"></div>',
130 link: function (scope
, elm
, attr
) {
131 var model
= $parse(attr
.crmAttachments
);
132 scope
.att
= model(scope
.$parent
);
133 scope
.ts
= CRM
.ts(null);
134 scope
.inclUrl
= partialUrl('attachments.html');
136 // delay rendering of child tree until after model has been populated
142 })(angular
, CRM
.$, CRM
._
);