This commit is contained in:
Yuri Kuznetsov
2024-03-29 09:33:48 +02:00
parent 34ecdd7533
commit 111e1a278c
2 changed files with 339 additions and 350 deletions
+118 -118
View File
@@ -26,142 +26,142 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
define('views/export/modals/export', ['views/modal', 'model'], function (Dep, Model) {
import ModalView from 'views/modal';
import Model from 'model';
return Dep.extend({
class ExportModalView extends ModalView {
cssName: 'export-modal',
cssName = 'export-modal'
className = 'dialog dialog-record'
template = 'export/modals/export'
className: 'dialog dialog-record',
shortcutKeys = {
'Control+Enter': 'export'
}
template: 'export/modals/export',
shortcutKeys: {
'Control+Enter': 'export',
},
data: function () {
return {};
},
setup: function () {
this.buttonList = [
{
name: 'export',
label: 'Export',
style: 'danger',
title: 'Ctrl+Enter',
},
{
name: 'cancel',
label: 'Cancel',
}
];
this.model = new Model();
this.model.name = 'Export';
this.scope = this.options.scope;
if (this.options.fieldList) {
const fieldList = this.options.fieldList
.filter(field => {
/** @type {Record} */
const defs = this.getMetadata().get(`entityDefs.${this.scope}.fields.${field}`) || {};
return !defs.exportDisabled && !defs.utility;
});
this.model.set('fieldList', fieldList);
this.model.set('exportAllFields', false);
} else {
this.model.set('exportAllFields', true);
setup() {
this.buttonList = [
{
name: 'export',
label: 'Export',
style: 'danger',
title: 'Ctrl+Enter',
},
{
name: 'cancel',
label: 'Cancel',
}
];
const formatList =
this.getMetadata().get(['scopes', this.scope, 'exportFormatList']) ||
this.getMetadata().get('app.export.formatList');
this.model = new Model();
this.model.name = 'Export';
this.model.set('format', formatList[0]);
this.scope = this.options.scope;
this.createView('record', 'views/export/record/record', {
scope: this.scope,
model: this.model,
selector: '.record',
formatList: formatList,
});
},
if (this.options.fieldList) {
const fieldList = this.options.fieldList
.filter(field => {
/** @type {Record} */
const defs = this.getMetadata().get(`entityDefs.${this.scope}.fields.${field}`) || {};
getRecordView: function () {
return this.getView('record');
},
actionExport: function () {
const recordView = this.getRecordView();
const data = recordView.fetch();
this.model.set(data);
if (recordView.validate()) {
return;
}
const returnData = {
exportAllFields: data.exportAllFields,
format: data.format,
};
if (!data.exportAllFields) {
const attributeList = [];
data.fieldList.forEach(item => {
if (item === 'id') {
attributeList.push('id');
return;
}
const type = this.getMetadata().get(['entityDefs', this.scope, 'fields', item, 'type']);
if (type) {
this.getFieldManager().getAttributeList(type, item)
.forEach(attribute => {
attributeList.push(attribute);
});
}
if (~item.indexOf('_')) {
attributeList.push(item);
}
return !defs.exportDisabled && !defs.utility;
});
returnData.attributeList = attributeList;
returnData.fieldList = data.fieldList;
}
this.model.set('fieldList', fieldList);
this.model.set('exportAllFields', false);
} else {
this.model.set('exportAllFields', true);
}
returnData.params = {};
const formatList =
this.getMetadata().get(['scopes', this.scope, 'exportFormatList']) ||
this.getMetadata().get('app.export.formatList');
recordView.getFormatParamList(data.format).forEach(param => {
const name = recordView.modifyParamName(data.format, param);
this.model.set('format', formatList[0]);
const fieldView = recordView.getFieldView(name);
this.createView('record', 'views/export/record/record', {
scope: this.scope,
model: this.model,
selector: '.record',
formatList: formatList,
});
}
/**
* @return {import('views/record/edit').default}
*/
getRecordView() {
return this.getView('record');
}
// noinspection JSUnusedGlobalSymbols
actionExport() {
const recordView = this.getRecordView();
const data = recordView.fetch();
this.model.set(data);
if (recordView.validate()) {
return;
}
const returnData = {
exportAllFields: data.exportAllFields,
format: data.format,
};
if (!data.exportAllFields) {
const attributeList = [];
data.fieldList.forEach(item => {
if (item === 'id') {
attributeList.push('id');
if (!fieldView || fieldView.disabled) {
return;
}
this.getFieldManager()
.getActualAttributeList(fieldView.type, param)
.forEach(subParam => {
const name = recordView.modifyParamName(data.format, subParam);
const type = this.getMetadata().get(['entityDefs', this.scope, 'fields', item, 'type']);
returnData.params[subParam] = data[name];
});
if (type) {
this.getFieldManager().getAttributeList(type, item)
.forEach(attribute => {
attributeList.push(attribute);
});
}
if (~item.indexOf('_')) {
attributeList.push(item);
}
});
this.trigger('proceed', returnData);
this.close();
},
});
});
returnData.attributeList = attributeList;
returnData.fieldList = data.fieldList;
}
returnData.params = {};
recordView.getFormatParamList(data.format).forEach(param => {
const name = recordView.modifyParamName(data.format, param);
const fieldView = recordView.getFieldView(name);
if (!fieldView || fieldView.disabled) {
return;
}
this.getFieldManager()
.getActualAttributeList(fieldView.type, param)
.forEach(subParam => {
const name = recordView.modifyParamName(data.format, subParam);
returnData.params[subParam] = data[name];
});
});
this.trigger('proceed', returnData);
this.close();
}
}
export default ExportModalView;
+221 -232
View File
@@ -26,282 +26,271 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
define('views/export/record/record', ['views/record/edit-for-modal'], function (Dep) {
import EditForModalRecordView from 'views/record/edit-for-modal';
class ExportRecordView extends EditForModalRecordView {
formatList = null
/**
* @class
* @name Class
* @memberOf module:views/export/record/record
* @extends module:views/record/edit-for-modal
* @type {Object.<string, string[]>},
*/
return Dep.extend(/** @lends module:views/export/record/record.Class# */{
customParams = null
/**
* @type {string[]},
*/
formatList: null,
/**
* @type {Object.<string, string[]>},
*/
customParams: null,
setupBeforeFinal() {
this.formatList = this.options.formatList;
this.scope = this.options.scope;
setup: function () {
Dep.prototype.setup.call(this);
},
const fieldsData = this.getExportFieldsData();
setupBeforeFinal: function () {
this.formatList = this.options.formatList;
this.scope = this.options.scope;
this.setupExportFieldDefs(fieldsData);
this.setupExportLayout(fieldsData);
this.setupExportDynamicLogic();
const fieldsData = this.getExportFieldsData();
this.controlFormatField();
this.listenTo(this.model, 'change:format', () => this.controlFormatField());
this.setupExportFieldDefs(fieldsData);
this.setupExportLayout(fieldsData);
this.setupExportDynamicLogic();
this.controlAllFields();
this.listenTo(this.model, 'change:exportAllFields', () => this.controlAllFields());
this.controlFormatField();
this.listenTo(this.model, 'change:format', () => this.controlFormatField());
super.setupBeforeFinal();
}
this.controlAllFields();
this.listenTo(this.model, 'change:exportAllFields', () => this.controlAllFields());
setupExportFieldDefs(fieldsData) {
const fieldDefs = {
format: {
type: 'enum',
options: this.formatList,
},
fieldList: {
type: 'multiEnum',
options: fieldsData.list,
required: true,
},
exportAllFields: {
type: 'bool',
},
};
Dep.prototype.setupBeforeFinal.call(this);
},
this.customParams = {};
setupExportFieldDefs: function (fieldsData) {
const fieldDefs = {
format: {
type: 'enum',
options: this.formatList,
},
fieldList: {
type: 'multiEnum',
options: fieldsData.list,
required: true,
},
exportAllFields: {
type: 'bool',
},
};
this.formatList.forEach(format => {
const fields = this.getFormatParamsDefs(format).fields || {};
this.customParams = {};
this.customParams[format] = [];
this.formatList.forEach(format => {
const fields = this.getFormatParamsDefs(format).fields || {};
for (const name in fields) {
const newName = this.modifyParamName(format, name);
this.customParams[format] = [];
this.customParams[format].push(name);
for (const name in fields) {
const newName = this.modifyParamName(format, name);
fieldDefs[newName] = Espo.Utils.cloneDeep(fields[name]);
}
});
this.customParams[format].push(name);
this.model.setDefs({fields: fieldDefs});
}
fieldDefs[newName] = Espo.Utils.cloneDeep(fields[name]);
}
});
setupExportLayout(fieldsData) {
this.detailLayout = [];
this.model.setDefs({fields: fieldDefs});
},
setupExportLayout: function (fieldsData) {
this.detailLayout = [];
const mainPanel = {
rows: [
[
{name: 'format'},
false
],
[
{name: 'exportAllFields'},
false
],
[
{
name: 'fieldList',
options: {
translatedOptions: fieldsData.translations,
},
}
],
]
};
this.detailLayout.push(mainPanel);
this.formatList.forEach(format => {
const rows = this.getFormatParamsDefs(format).layout || [];
rows.forEach(row => {
row.forEach(item => {
item.name = this.modifyParamName(format, item.name);
});
})
this.detailLayout.push({
name: format,
rows: rows,
})
});
},
setupExportDynamicLogic: function () {
this.dynamicLogicDefs = {
fields: {},
};
this.formatList.forEach(format => {
const defs = this.getFormatParamsDefs(format).dynamicLogic || {};
this.customParams[format].forEach(param => {
const logic = defs[param] || {};
if (!logic.visible) {
logic.visible = {};
const mainPanel = {
rows: [
[
{name: 'format'},
false
],
[
{name: 'exportAllFields'},
false
],
[
{
name: 'fieldList',
options: {
translatedOptions: fieldsData.translations,
},
}
],
]
};
if (!logic.visible.conditionGroup) {
logic.visible.conditionGroup = [];
}
this.detailLayout.push(mainPanel);
logic.visible.conditionGroup.push({
type: 'equals',
attribute: 'format',
value: format,
});
this.formatList.forEach(format => {
const rows = this.getFormatParamsDefs(format).layout || [];
const newName = this.modifyParamName(format, param);
this.dynamicLogicDefs.fields[newName] = logic;
rows.forEach(row => {
row.forEach(item => {
item.name = this.modifyParamName(format, item.name);
});
});
},
})
/**
* @param {string} format
* @return {string[]}
*/
getFormatParamList: function (format) {
return Object.keys(this.getFormatParamsDefs(format).fields || {});
},
this.detailLayout.push({
name: format,
rows: rows,
})
});
}
/**
* @private
* @return {Object.<string, *>}
*/
getFormatParamsDefs: function (format) {
const defs = this.getMetadata().get(['app', 'export', 'formatDefs', format]) || {};
setupExportDynamicLogic() {
this.dynamicLogicDefs = {
fields: {},
};
return Espo.Utils.cloneDeep(defs.params || {});
},
this.formatList.forEach(format => {
const defs = this.getFormatParamsDefs(format).dynamicLogic || {};
/**
* @param {string} format
* @param {string} name
* @return {string}
*/
modifyParamName: function (format, name) {
return format + Espo.Utils.upperCaseFirst(name);
},
this.customParams[format].forEach(param => {
const logic = defs[param] || {};
/**
* @return {{
* translations: Object.<string, string>,
* list: string[]
* }}
*/
getExportFieldsData: function () {
let fieldList = this.getFieldManager().getEntityTypeFieldList(this.scope);
const forbiddenFieldList = this.getAcl().getScopeForbiddenFieldList(this.scope);
fieldList = fieldList.filter(item => {
return !~forbiddenFieldList.indexOf(item);
});
fieldList = fieldList.filter(item => {
/** @type {Record} */
const defs = this.getMetadata().get(['entityDefs', this.scope, 'fields', item]) || {};
if (
defs.disabled ||
defs.exportDisabled ||
defs.type === 'map' ||
defs.utility
) {
return false
if (!logic.visible) {
logic.visible = {};
}
return true;
});
this.getLanguage().sortFieldList(this.scope, fieldList);
fieldList.unshift('id');
const fieldListTranslations = {};
fieldList.forEach(item => {
fieldListTranslations[item] = this.getLanguage().translate(item, 'fields', this.scope);
});
const setFieldList = this.model.get('fieldList') || [];
setFieldList.forEach(item => {
if (~fieldList.indexOf(item)) {
return;
if (!logic.visible.conditionGroup) {
logic.visible.conditionGroup = [];
}
if (!~item.indexOf('_')) {
return;
}
logic.visible.conditionGroup.push({
type: 'equals',
attribute: 'format',
value: format,
});
const arr = item.split('_');
const newName = this.modifyParamName(format, param);
fieldList.push(item);
const foreignScope = this.getMetadata().get(['entityDefs', this.scope, 'links', arr[0], 'entity']);
if (!foreignScope) {
return;
}
fieldListTranslations[item] = this.getLanguage().translate(arr[0], 'links', this.scope) + '.' +
this.getLanguage().translate(arr[1], 'fields', foreignScope);
this.dynamicLogicDefs.fields[newName] = logic;
});
});
}
return {
list: fieldList,
translations: fieldListTranslations,
};
},
/**
* @param {string} format
* @return {string[]}
*/
getFormatParamList(format) {
return Object.keys(this.getFormatParamsDefs(format).fields || {});
}
controlAllFields: function () {
if (!this.model.get('exportAllFields')) {
this.showField('fieldList');
/**
* @private
* @return {Object.<string, *>}
*/
getFormatParamsDefs(format) {
const defs = this.getMetadata().get(['app', 'export', 'formatDefs', format]) || {};
return Espo.Utils.cloneDeep(defs.params || {});
}
/**
* @param {string} format
* @param {string} name
* @return {string}
*/
modifyParamName(format, name) {
return format + Espo.Utils.upperCaseFirst(name);
}
/**
* @return {{
* translations: Object.<string, string>,
* list: string[]
* }}
*/
getExportFieldsData() {
let fieldList = this.getFieldManager().getEntityTypeFieldList(this.scope);
const forbiddenFieldList = this.getAcl().getScopeForbiddenFieldList(this.scope);
fieldList = fieldList.filter(item => {
return !~forbiddenFieldList.indexOf(item);
});
fieldList = fieldList.filter(item => {
/** @type {Record} */
const defs = this.getMetadata().get(['entityDefs', this.scope, 'fields', item]) || {};
if (
defs.disabled ||
defs.exportDisabled ||
defs.type === 'map' ||
defs.utility
) {
return false
}
return true;
});
this.getLanguage().sortFieldList(this.scope, fieldList);
fieldList.unshift('id');
const fieldListTranslations = {};
fieldList.forEach(item => {
fieldListTranslations[item] = this.getLanguage().translate(item, 'fields', this.scope);
});
const setFieldList = this.model.get('fieldList') || [];
setFieldList.forEach(item => {
if (~fieldList.indexOf(item)) {
return;
}
this.hideField('fieldList');
},
if (!~item.indexOf('_')) {
return;
}
controlFormatField: function () {
const format = this.model.get('format');
const arr = item.split('_');
this.formatList
.filter(item => item !== format)
.forEach(format => {
fieldList.push(item);
const foreignScope = this.getMetadata().get(['entityDefs', this.scope, 'links', arr[0], 'entity']);
if (!foreignScope) {
return;
}
fieldListTranslations[item] = this.getLanguage().translate(arr[0], 'links', this.scope) + '.' +
this.getLanguage().translate(arr[1], 'fields', foreignScope);
});
return {
list: fieldList,
translations: fieldListTranslations,
};
}
controlAllFields() {
if (!this.model.get('exportAllFields')) {
this.showField('fieldList');
return;
}
this.hideField('fieldList');
}
controlFormatField() {
const format = this.model.get('format');
this.formatList
.filter(item => item !== format)
.forEach(format => {
this.hidePanel(format);
});
this.formatList
.filter(item => item === format)
.forEach(format => {
this.customParams[format].length ?
this.showPanel(format) :
this.hidePanel(format);
});
});
}
}
this.formatList
.filter(item => item === format)
.forEach(format => {
this.customParams[format].length ?
this.showPanel(format) :
this.hidePanel(format);
});
},
});
});
export default ExportRecordView;