diff --git a/client/src/views/modals/edit.js b/client/src/views/modals/edit.js index e3c366754f..0e939ac3da 100644 --- a/client/src/views/modals/edit.js +++ b/client/src/views/modals/edit.js @@ -26,7 +26,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -Espo.define('views/modals/edit', 'views/modal', function (Dep) { +define('views/modals/edit', 'views/modal', function (Dep) { return Dep.extend({ diff --git a/client/src/views/record/base.js b/client/src/views/record/base.js index 34a4ce45a8..f3317915c7 100644 --- a/client/src/views/record/base.js +++ b/client/src/views/record/base.js @@ -544,14 +544,17 @@ define( this.notify('Not valid', 'error'); }, - save: function (callback, skipExit, errorCallback) { + save: function (options) { + options = options || {}; + + var headers = options.headers || {}; + this.lastSaveCancelReason = null; this.beforeBeforeSave(); var data = this.fetch(); - var self = this; var model = this.model; var initialAttributes = this.attributes; @@ -582,7 +585,9 @@ define( this.trigger('cancel:save', {reason: 'notModified'}); - return true; + return new Promise(function (resolve, reject) { + reject('notModified'); + }); } model.set(setAttributes, {silent: true}); @@ -596,7 +601,9 @@ define( this.trigger('cancel:save', {reason: 'invalid'}); - return; + return new Promise(function (resolve, reject) { + reject('invalid'); + }); } this.beforeSave(); @@ -605,56 +612,52 @@ define( model.trigger('before:save'); - model.save(setAttributes, { - success: function () { - this.afterSave(); - - var isNew = self.isNew; - - if (self.isNew) { - self.isNew = false; + return new Promise(function (resolve, reject) { + model.save( + setAttributes, + { + patch: !model.isNew(), + headers: headers, } + ) + .then( + function () { + this.afterSave(); - this.trigger('after:save'); + var isNew = this.isNew; - model.trigger('after:save'); - - if (!callback) { - if (!skipExit) { - if (isNew) { - this.exit('create'); - } else { - this.exit('save'); + if (this.isNew) { + this.isNew = false; } - } - } else { - callback(this); - } - }.bind(this), - error: function (e, xhr) { - this.handleSaveError(e, xhr); - this.afterSaveError(); + this.trigger('after:save'); - this.setModelAttributes(beforeSaveAttributes); + model.trigger('after:save'); - this.lastSaveCancelReason = 'error'; + resolve(); - this.trigger('error:save'); - this.trigger('cancel:save', {reason: 'error'}); + }.bind(this) + ) + .fail( + function (xhr) { + this.handleSaveError(xhr); - if (errorCallback) { - errorCallback.call(this, xhr); - } - }.bind(this), + this.afterSaveError(); - patch: !model.isNew() - }); + this.setModelAttributes(beforeSaveAttributes); - return true; + this.lastSaveCancelReason = 'error'; + + this.trigger('error:save'); + this.trigger('cancel:save', {reason: 'error'}); + + reject('error'); + }.bind(this) + ); + }.bind(this)); }, - handleSaveError: function (e, xhr) { + handleSaveError: function (xhr) { var response = null; if (~[409, 500].indexOf(xhr.status)) { diff --git a/client/src/views/record/detail.js b/client/src/views/record/detail.js index 3305985005..f7bb5411c0 100644 --- a/client/src/views/record/detail.js +++ b/client/src/views/record/detail.js @@ -120,7 +120,7 @@ define('views/record/detail', ['views/record/base', 'view-record-helper'], funct convertCurrencyAction: true, - saveAndContinueEditingAction: false, + saveAndContinueEditingAction: true, panelSoftLockedTypeList: ['default', 'acl', 'delimiter', 'dynamicLogic'], @@ -159,16 +159,21 @@ define('views/record/detail', ['views/record/base', 'view-record-helper'], funct this.delete(); }, - actionSave: function () { + actionSave: function (data) { + data = data || {}; + var modeBeforeSave = this.mode; - var errorCallback = function () { - if (modeBeforeSave === 'edit') { - this.setEditMode(); - } - }.bind(this); + this.save(data.options) + .catch( + function (reason) { + if (modeBeforeSave === 'edit' && reason === 'error') { + this.setEditMode(); + } + }.bind(this) + ); - if (this.save(null, true, errorCallback)) { + if (!this.lastSaveCancelReason || this.lastSaveCancelReason === 'notModified') { this.setDetailMode(); $(window).scrollTop(0); @@ -181,8 +186,11 @@ define('views/record/detail', ['views/record/base', 'view-record-helper'], funct $(window).scrollTop(0); }, - actionSaveAndContinueEditing: function () { - this.save(null, true); + actionSaveAndContinueEditing: function (data) { + data = data || {}; + + this.save(data.options) + .catch(function () {}); }, actionSelfAssign: function () { @@ -1507,11 +1515,14 @@ define('views/record/detail', ['views/record/base', 'view-record-helper'], funct view.render(); this.listenToOnce(view, 'save', function () { - this.model.set('_skipDuplicateCheck', true); - - this.actionSave(); + this.actionSave({ + options: { + headers: { + 'X-Skip-Duplicate-Check': 'true', + } + } + }); }.bind(this)); - }.bind(this)); }, diff --git a/client/src/views/record/edit.js b/client/src/views/record/edit.js index 0d040a2176..6a71b0cb25 100644 --- a/client/src/views/record/edit.js +++ b/client/src/views/record/edit.js @@ -64,8 +64,16 @@ define('views/record/edit', 'views/record/detail', function (Dep) { saveAndNewAction: true, - actionSave: function () { - this.save(); + actionSave: function (data) { + var isNew = this.isNew; + + this.save(data.options) + .then( + function () { + this.exit(isNew ? 'create' : 'save'); + }.bind(this) + ) + .catch(function () {}); }, actionCancel: function () { @@ -76,6 +84,7 @@ define('views/record/edit', 'views/record/detail', function (Dep) { if (this.isChanged) { this.resetModelChanges(); } + this.setIsNotChanged(); this.exit('cancel'); }, @@ -84,6 +93,7 @@ define('views/record/edit', 'views/record/detail', function (Dep) { if (this.model.isNew()) { this.populateDefaults(); } + Dep.prototype.setupBeforeFinal.call(this); }, @@ -112,7 +122,9 @@ define('views/record/edit', 'views/record/detail', function (Dep) { } }, - actionSaveAndNew: function () { + actionSaveAndNew: function (data) { + data = data || {}; + var proceedCallback = function () { Espo.Ui.success(this.translate('Created')); @@ -123,7 +135,9 @@ define('views/record/edit', 'views/record/detail', function (Dep) { this.getRouter().navigate('#' + this.scope + '/create', {trigger: false}); }.bind(this) - this.save(proceedCallback, true); + this.save(data.options) + .then(proceedCallback) + .catch(function () {}); if (this.lastSaveCancelReason === 'notModified') { proceedCallback();