Commit | Line | Data |
---|---|---|
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._); |