save change

This commit is contained in:
Yuri Kuznetsov
2024-11-18 16:34:05 +02:00
parent edfd816fc6
commit 16e82cde65
2 changed files with 75 additions and 93 deletions
+74 -92
View File
@@ -720,22 +720,6 @@ class BaseRecordView extends View {
this.model.set(this.attributes, {skipReRender: true});
}
/**
* Set model attribute values.
*
* @param {Object.<string,*>} setAttributes Values.
* @param {Object.<string,*>} [options] Options.
*/
setModelAttributes(setAttributes, options) {
for (const item in this.model.attributes) {
if (!(item in setAttributes)) {
this.model.unset(item);
}
}
this.model.set(setAttributes, options || {});
}
/**
* Init dynamic logic.
*
@@ -986,6 +970,54 @@ class BaseRecordView extends View {
Espo.Ui.error(this.translate('Not valid'));
}
/**
* Get changed attribute values. For new record, returns all attributes.
*
* @protected
* @param {string[]} [attributeList]
* @return {Record}
*/
getChangedAttributes(attributeList = null) {
const attributes = this.model.getClonedAttributes();
if (this.model.isNew()) {
return attributes;
}
const setAttributes = {};
for (const attr in attributes) {
if (Espo.Utils.areEqual(this.attributes[attr], attributes[attr])) {
continue;
}
setAttributes[attr] = attributes[attr];
}
/** @type {Record.<string, string[]>} */
const map = this.forcePatchAttributeDependencyMap || {};
for (const attr in map) {
if (attr in setAttributes) {
continue;
}
if (attributeList && !attributeList.includes(attr)) {
continue;
}
const depAttributes = map[attr];
const treatAsChanged = !!depAttributes.find(attr => attr in setAttributes);
if (treatAsChanged) {
setAttributes[attr] = attributes[attr];
}
}
return setAttributes;
}
/**
* Save options.
*
@@ -1014,50 +1046,15 @@ class BaseRecordView extends View {
this.beforeBeforeSave();
// A model is supposed to always contain actual values.
// Fetch may not be needed, but some field views may not have data sync implemented.
// We resort to fetching the entire form.
const fetchedAttributes = this.fetch();
const initialAttributes = this.attributes;
const beforeSaveAttributes = this.model.getClonedAttributes();
const attributes = _.extend(
Espo.Utils.cloneDeep(beforeSaveAttributes),
fetchedAttributes
);
this.model.set(fetchedAttributes, {silent: true});
let setAttributes = {};
if (model.isNew()) {
setAttributes = attributes;
}
if (!model.isNew()) {
for (const attr in attributes) {
if (_.isEqual(initialAttributes[attr], attributes[attr])) {
continue;
}
setAttributes[attr] = attributes[attr];
}
const forcePatchAttributeDependencyMap = this.forcePatchAttributeDependencyMap || {};
for (const attr in forcePatchAttributeDependencyMap) {
if (attr in setAttributes) {
continue;
}
if (!(attr in fetchedAttributes)) {
continue;
}
const depAttributeList = forcePatchAttributeDependencyMap[attr];
const treatAsChanged = !!depAttributeList.find(attr => attr in setAttributes);
if (treatAsChanged) {
setAttributes[attr] = attributes[attr];
}
}
}
const setAttributes = this.getChangedAttributes(Object.keys(fetchedAttributes));
if (Object.keys(setAttributes).length === 0) {
if (!options.skipNotModifiedWarning) {
@@ -1071,11 +1068,7 @@ class BaseRecordView extends View {
return Promise.reject('notModified');
}
model.set(setAttributes, {silent: true});
if (this.validate()) {
model.attributes = beforeSaveAttributes;
this.afterNotValid();
this.lastSaveCancelReason = 'invalid';
@@ -1105,39 +1098,14 @@ class BaseRecordView extends View {
this.trigger('before:save');
model.trigger('before:save');
const onError = (xhr, reject, resolve) => {
this.handleSaveError(xhr, options, resolve, reject)
.then(skipReject => {
if (skipReject) {
return;
}
reject('error');
});
this.afterSaveError();
if (!options.bypassClose) {
this.setModelAttributes(beforeSaveAttributes);
}
this.lastSaveCancelReason = 'error';
this.trigger('error:save');
this.trigger('cancel:save', {reason: 'error'});
};
return new Promise((resolve, reject) => {
model
.save(
setAttributes,
{
patch: !model.isNew(),
headers: headers,
},
)
.save(setAttributes, {
patch: !model.isNew(),
headers: headers,
})
.then(() => {
this.trigger('save', initialAttributes, Object.keys(setAttributes));
this.trigger('save', this.attributes, Object.keys(setAttributes));
this.afterSave();
@@ -1151,7 +1119,21 @@ class BaseRecordView extends View {
resolve();
})
.catch(xhr => {
onError(xhr, reject, resolve);
this.handleSaveError(xhr, options, resolve, reject)
.then(skipReject => {
if (skipReject) {
return;
}
reject('error');
});
this.afterSaveError();
this.lastSaveCancelReason = 'error';
this.trigger('error:save');
this.trigger('cancel:save', {reason: 'error'});
});
});
}
+1 -1
View File
@@ -635,7 +635,7 @@ class DetailRecordView extends BaseRecordView {
options.rootUrl = this.options.rootUrl;
}
this.getRouter().navigate('#' + this.scope + '/edit/' + this.model.id, {trigger: false});
this.getRouter().navigate(`#${this.scope}/edit/${this.model.id}`, {trigger: false});
this.getRouter().dispatch(this.scope, 'edit', options);
}