CRM-15855 - crmMailing - Fix autosave for attachments
authorTim Otten <totten@civicrm.org>
Wed, 28 Jan 2015 05:44:03 +0000 (21:44 -0800)
committerTim Otten <totten@civicrm.org>
Wed, 28 Jan 2015 05:44:03 +0000 (21:44 -0800)
js/angular-crmAttachment.js
partials/crmMailing/edit-unified.html
partials/crmMailing/edit-unified2.html
partials/crmMailing/edit-wizard.html
partials/crmMailing/edit.html

index a859f9258729f97a88d88fe38980387a67259a9f..35dd1c582fe22fa8396b914c2321e1ff76775b1e 100644 (file)
@@ -10,6 +10,7 @@
       var crmAttachments = this;
       this._target = target;
       this.files = [];
+      this.trash = [];
       this.uploader = new FileUploader({
         url: CRM.url('civicrm/ajax/attachment'),
         onAfterAddingFile: function onAfterAddingFile(item) {
             return dfr.promise;
           });
       },
+      // Compute a digest over the list of files. The signature should change if the attachment list has changed
+      // (become dirty).
+      getAutosaveSignature: function getAutosaveSignature() {
+        var sig = [];
+        // Attachments have a special lifecycle, and attachments.queue is not properly serializable, so
+        // it takes some special effort to figure out a suitable signature. Issues which can cause gratuitous saving:
+        //  - Files move from this.uploader.queue to this.files after upload.
+        //  - File names are munged after upload.
+        //  - Deletes are performed immediately (outside the save process).
+        angular.forEach(this.files, function(item) {
+          sig.push({f: item.name.replace(/[^a-zA0-Z0-9\.]/, '_'), d: item.description});
+        });
+        angular.forEach(this.uploader.queue, function(item) {
+          sig.push({f: item.file.name.replace(/[^a-zA0-Z0-9\.]/, '_'), d: item.crmData.description});
+        });
+        angular.forEach(this.trash, function(item) {
+          sig.push({f: item.name.replace(/[^a-zA0-Z0-9\.]/, '_'), d: item.description});
+        });
+        return _.sortBy(sig, 'name');
+      },
       // @param Object file APIv3 attachment record (e.g. id, entity_table, entity_id, description)
       deleteFile: function deleteFile(file) {
         var crmAttachments = this;
           this.files.splice(idx, 1);
         }
 
+        this.trash.push(file);
+
         if (file.id) {
           var p = crmApi('Attachment', 'delete', {id: file.id}).then(
             function () { // success
               var msg = angular.isObject(response) ? response.error_message : '';
               CRM.alert(msg, ts('Deletion failed'));
               crmAttachments.files.push(file);
+
+              var trashIdx = _.indexOf(crmAttachments.trash, file);
+              if (trashIdx != -1) {
+                crmAttachments.trash.splice(trashIdx, 1);
+              }
             }
           );
           return crmStatus({start: ts('Deleting...'), success: ts('Deleted')}, p);
index 6e46a03ff31e92dd94d4d07564b37d0cfa67237d..24e497c67b560ca1943e1d3d95f69bc2ce20a298 100644 (file)
@@ -6,7 +6,7 @@
   {{ts('This mailing has been submitted.')}}
 </div>
 
-<form name="crmMailing" novalidate ng-hide="isSubmitted()" crm-autosave="save()" crm-autosave-model="mailing" crm-autosave-if="true">
+<form name="crmMailing" novalidate ng-hide="isSubmitted()" crm-autosave="save()" crm-autosave-model="[mailing, attachments.getAutosaveSignature()]" crm-autosave-if="true">
   <div class="crm-block crm-form-block crmMailing">
 
     <div crm-mailing-block-summary crm-mailing="mailing"/>
index eee356fd51cd87e5a94efd7eb88648c78c6eb2b8..1d1916086c52678c3b1d725407fcce6967e833c0 100644 (file)
@@ -6,7 +6,7 @@
   {{ts('This mailing has been submitted.')}}
 </div>
 
-<form name="crmMailing" novalidate ng-hide="isSubmitted()" crm-autosave="save()" crm-autosave-model="mailing" crm-autosave-if="true">
+<form name="crmMailing" novalidate ng-hide="isSubmitted()" crm-autosave="save()" crm-autosave-model="[mailing, attachments.getAutosaveSignature()]" crm-autosave-if="true">
   <div class="crm-block crm-form-block crmMailing">
 
     <div crm-mailing-block-summary crm-mailing="mailing"/>
index 0a05f22e58a9199821eb0169574c45682afecd79..7bda0d62c84e16392711da464aa95fbfa7698aaf 100644 (file)
@@ -6,7 +6,7 @@
   {{ts('This mailing has been submitted.')}}
 </div>
 
-<form name="crmMailing" novalidate ng-hide="isSubmitted()" crm-autosave="save()" crm-autosave-model="mailing" crm-autosave-if="true">
+<form name="crmMailing" novalidate ng-hide="isSubmitted()" crm-autosave="save()" crm-autosave-model="[mailing, attachments.getAutosaveSignature()]" crm-autosave-if="true">
   <div class="crm-block crm-form-block crmMailing">
 
     <div crm-ui-wizard>
index adac47dd88066647dfed7c32c9ec888f28882d76..6c33c71554e82d4fee3911a20b17ab018ca89353 100644 (file)
@@ -6,7 +6,7 @@
   {{ts('This mailing has been submitted.')}}
 </div>
 
-<form name="crmMailing" novalidate ng-hide="isSubmitted()" crm-autosave="save()" crm-autosave-model="mailing" crm-autosave-if="true">
+<form name="crmMailing" novalidate ng-hide="isSubmitted()" crm-autosave="save()" crm-autosave-model="[mailing, attachments.getAutosaveSignature()]" crm-autosave-if="true">
 
   <div class="crm-block crm-form-block crmMailing">
     <div crm-ui-wizard>