cascade removal

This commit is contained in:
Yurii
2026-03-05 09:46:30 +02:00
parent 9e2029dc0a
commit 8561b1af65
16 changed files with 602 additions and 27 deletions
+2 -1
View File
@@ -180,7 +180,8 @@ class LinkManagerIndexView extends View {
const isRemovable = defs.isCustom;
const hasEditParams = defs.type === 'hasMany' || defs.type === 'hasChildren';
const hasEditParams = ['hasChildren', 'hasMany'].includes(defs.type) ||
['oneToOneLeft', 'oneToOneRight', 'oneToMany'].includes(type);
this.linkDataList.push({
link: link,
@@ -43,6 +43,18 @@ export default class LinkManagerEditParamsModalView extends ModalView {
*/
type
/**
* @private
* @type {string|null}
*/
foreignType = null
/**
* @private
* @type {string|null}
*/
foreignEntityType
/**
* @param {{
* entityType: string,
@@ -60,10 +72,21 @@ export default class LinkManagerEditParamsModalView extends ModalView {
this.translate(this.props.entityType, 'scopeNames') + ' · ' +
this.translate(this.props.link, 'links', this.props.entityType);
/** @type {{type: string, isCustom: boolean}} */
this.systemEntityTypeList = ['User', 'Team'];
/** @type {{type: string, isCustom?: boolean, entity?: string, foreign?: string|null}} */
const defs = this.getMetadata().get(`entityDefs.${this.props.entityType}.links.${this.props.link}`) || {};
this.type = defs.type;
const foreignEntityType = defs.entity ?? null;
const foreign = defs.foreign;
this.foreignEntityType = foreignEntityType;
if (foreignEntityType && foreign) {
this.foreignType = this.getMetadata().get(`entityDefs.${foreignEntityType}.links.${foreign}.type`);
}
this.buttonList = [
{
name: 'save',
@@ -104,18 +127,35 @@ export default class LinkManagerEditParamsModalView extends ModalView {
}),
},
false
],
[
{
view: new BoolFieldView({
name: 'cascadeRemoval',
labelText: this.translate('cascadeRemoval', 'fields', 'Admin'),
params: {
tooltip: 'EntityManager.linkParamCascadeRemoval',
},
}),
},
false
]
]
}
]
});
if (!this.hasReadOnly()) {
this.recordView.hideField('readOnly');
this.recordView.setFieldReadOnly('readOnly');
}
this.assignView('record', this.recordView).then(() => {
if (!this.hasReadOnly()) {
this.recordView.hideField('readOnly');
this.recordView.setFieldReadOnly('readOnly');
}
this.assignView('record', this.recordView, '.record');
if (!this.hasCascadeRemoval()) {
this.recordView.hideField('cascadeRemoval');
this.recordView.setFieldReadOnly('cascadeRemoval');
}
});
}
/**
@@ -126,6 +166,23 @@ export default class LinkManagerEditParamsModalView extends ModalView {
return ['hasMany', 'hasChildren'].includes(this.type);
}
/**
* @private
* @return {boolean}
*/
hasCascadeRemoval() {
if (!this.foreignEntityType) {
return false;
}
const isObject = this.getMetadata().get(`scopes.${this.foreignEntityType}.object`) &&
!this.systemEntityTypeList.includes(this.foreignEntityType);
return ['hasChildren', 'hasOne'].includes(this.type) ||
(this.type === 'belongsTo' && this.foreignType === 'hasOne') ||
(this.type === 'hasMany' && this.foreignType === 'belongsTo');
}
/**
* @private
* @return {Record}
@@ -135,7 +192,8 @@ export default class LinkManagerEditParamsModalView extends ModalView {
const defs = this.getMetadata().get(`entityDefs.${this.props.entityType}.links.${this.props.link}`) || {};
return {
readOnly: defs.readOnly || false,
readOnly: defs.readOnly ?? false,
cascadeRemoval: defs.cascadeRemoval ?? false,
};
}
@@ -172,6 +230,10 @@ export default class LinkManagerEditParamsModalView extends ModalView {
params.readOnly = this.formModel.attributes.readOnly;
}
if (this.hasCascadeRemoval()) {
params.cascadeRemoval = this.formModel.attributes.cascadeRemoval;
}
try {
await Espo.Ajax.postRequest('EntityManager/action/updateLinkParams', {
entityType: this.props.entityType,