mirror of
https://github.com/espocrm/espocrm.git
synced 2026-06-28 06:56:05 +00:00
export params
This commit is contained in:
@@ -43,21 +43,15 @@ use stdClass;
|
||||
|
||||
class Export
|
||||
{
|
||||
private $service;
|
||||
|
||||
public function __construct(Service $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
}
|
||||
public function __construct(private Service $service)
|
||||
{}
|
||||
|
||||
public function postActionProcess(Request $request): stdClass
|
||||
{
|
||||
$params = $this->fetchRawParamsFromRequest($request);
|
||||
|
||||
$serviceParams = ServiceParams::create()
|
||||
->withIsIdle(
|
||||
$request->getParsedBody()->idle ?? false
|
||||
);
|
||||
->withIsIdle($request->getParsedBody()->idle ?? false);
|
||||
|
||||
$result = $this->service->process($params, $serviceParams);
|
||||
|
||||
@@ -141,6 +135,14 @@ class Export
|
||||
$params['format'] = $data->format;
|
||||
}
|
||||
|
||||
return Params::fromRaw($params);
|
||||
$obj = Params::fromRaw($params);
|
||||
|
||||
if (isset($data->params) && $data->params instanceof stdClass) {
|
||||
foreach (get_object_vars($data->params) as $key => $value) {
|
||||
$obj = $obj->withParam($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
"exportAllFields": "Export all fields",
|
||||
"fieldList": "Field List",
|
||||
"format": "Format",
|
||||
"status": "Status"
|
||||
"status": "Status",
|
||||
"xlsxRecordLinks": "Record Links",
|
||||
"xlsxTitleRow": "Title Row"
|
||||
},
|
||||
"options": {
|
||||
"format": {
|
||||
@@ -17,6 +19,9 @@
|
||||
"Failed": "Failed"
|
||||
}
|
||||
},
|
||||
"tooltips": {
|
||||
"xlsxTitleRow": "Title and date in the first row."
|
||||
},
|
||||
"messages": {
|
||||
"exportProcessed": "Export has been processed. Download the [file]({url}).",
|
||||
"infoText": "The export is being processed in idle by cron. It can take some time to finish. Closing this modal dialog won't affect the execution process."
|
||||
|
||||
@@ -37,6 +37,25 @@
|
||||
"enum": "Espo\\Tools\\Export\\Format\\Xlsx\\CellValuePreparators\\Enumeration",
|
||||
"multiEnum": "Espo\\Tools\\Export\\Format\\Xlsx\\CellValuePreparators\\MultiEnum",
|
||||
"array": "Espo\\Tools\\Export\\Format\\Xlsx\\CellValuePreparators\\MultiEnum"
|
||||
},
|
||||
"params": {
|
||||
"fields": {
|
||||
"recordLinks": {
|
||||
"type": "bool",
|
||||
"default": false
|
||||
},
|
||||
"titleRow": {
|
||||
"type": "bool",
|
||||
"default": true,
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"layout": [
|
||||
[
|
||||
{"name": "recordLinks"},
|
||||
{"name": "titleRow"}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,9 +176,15 @@ class Export
|
||||
$fileName . '.' . $fileExtension :
|
||||
"Export_{$entityType}.{$fileExtension}";
|
||||
|
||||
return (new ProcessorParams($fileName, $attributeList, $fieldList))
|
||||
$processorParams = (new ProcessorParams($fileName, $attributeList, $fieldList))
|
||||
->withName($params->getName())
|
||||
->withEntityType($params->getEntityType());
|
||||
|
||||
foreach ($params->getParamList() as $n) {
|
||||
$processorParams = $processorParams->withParam($n, $params->getParam($n));
|
||||
}
|
||||
|
||||
return $processorParams;
|
||||
}
|
||||
|
||||
private function getForeignAttributeType(Entity $entity, string $attribute): ?string
|
||||
|
||||
@@ -66,6 +66,8 @@ use RuntimeException;
|
||||
class Processor implements ProcessorInterface
|
||||
{
|
||||
private const FORMAT = 'xlsx';
|
||||
private const PARAM_RECORD_LINKS = 'recordLinks';
|
||||
private const PARAM_TITLE_ROW = 'titleRow';
|
||||
|
||||
/** @var array<string, CellValuePreparator> */
|
||||
private array $preparatorsCache = [];
|
||||
@@ -134,20 +136,22 @@ class Processor implements ProcessorInterface
|
||||
$now = new DateTime();
|
||||
$now->setTimezone(new DateTimeZone($this->config->get('timeZone', 'UTC')));
|
||||
|
||||
$sheet->setCellValue('A1', $this->sanitizeCellValue($exportName));
|
||||
$sheet->setCellValue('B1',
|
||||
SharedDate::PHPToExcel(strtotime($now->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT)))
|
||||
);
|
||||
if ($params->getParam(self::PARAM_TITLE_ROW)) {
|
||||
$sheet->setCellValue('A1', $this->sanitizeCellValue($exportName));
|
||||
$sheet->setCellValue('B1',
|
||||
SharedDate::PHPToExcel(strtotime($now->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT)))
|
||||
);
|
||||
|
||||
$sheet->getStyle('A1')->applyFromArray($this->titleStyle);
|
||||
$sheet->getStyle('B1')->applyFromArray($this->dateStyle);
|
||||
$sheet->getStyle('B1')
|
||||
->getNumberFormat()
|
||||
->setFormatCode($this->dateTime->getDateTimeFormat());
|
||||
$sheet->getStyle('A1')->applyFromArray($this->titleStyle);
|
||||
$sheet->getStyle('B1')->applyFromArray($this->dateStyle);
|
||||
$sheet->getStyle('B1')
|
||||
->getNumberFormat()
|
||||
->setFormatCode($this->dateTime->getDateTimeFormat());
|
||||
}
|
||||
|
||||
$azRange = $this->getColumnsRange($fieldList);
|
||||
|
||||
$rowNumber = 3;
|
||||
$rowNumber = $params->getParam(self::PARAM_TITLE_ROW) ? 3 : 1;
|
||||
$linkColList = [];
|
||||
$lastIndex = 0;
|
||||
|
||||
@@ -176,9 +180,13 @@ class Processor implements ProcessorInterface
|
||||
$sheet->setCellValue($col . $rowNumber, $this->sanitizeCellValue($label));
|
||||
$sheet->getColumnDimension($col)->setAutoSize(true);
|
||||
|
||||
$linkTypeList = $params->getParam(self::PARAM_RECORD_LINKS) ?
|
||||
['url', 'phone', 'email', 'link', 'linkParent'] :
|
||||
['url'];
|
||||
|
||||
if (
|
||||
in_array($type, ['phone', 'email', 'url', 'link', 'linkParent']) ||
|
||||
$name === 'name'
|
||||
in_array($type, $linkTypeList) ||
|
||||
$params->getParam(self::PARAM_RECORD_LINKS) && $name === 'name'
|
||||
) {
|
||||
$linkColList[] = $col;
|
||||
}
|
||||
|
||||
@@ -40,19 +40,16 @@ use RuntimeException;
|
||||
class Params
|
||||
{
|
||||
private string $entityType;
|
||||
/**
|
||||
* @var ?string[]
|
||||
*/
|
||||
/** @var ?string[] */
|
||||
private $attributeList = null;
|
||||
/**
|
||||
* @var ?string[]
|
||||
*/
|
||||
/** @var ?string[] */
|
||||
private $fieldList = null;
|
||||
private ?string $fileName = null;
|
||||
private ?string $format = null;
|
||||
private ?string $name = null;
|
||||
/** @var array<string, mixed> */
|
||||
private array $params = [];
|
||||
private ?SearchParams $searchParams = null;
|
||||
|
||||
private bool $applyAccessControl = true;
|
||||
|
||||
public function __construct(string $entityType)
|
||||
@@ -61,7 +58,7 @@ class Params
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $params
|
||||
* @param array<string, mixed> $params
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function fromRaw(array $params): self
|
||||
@@ -144,7 +141,6 @@ class Params
|
||||
public function withFormat(?string $format): self
|
||||
{
|
||||
$obj = clone $this;
|
||||
|
||||
$obj->format = $format;
|
||||
|
||||
return $obj;
|
||||
@@ -153,7 +149,6 @@ class Params
|
||||
public function withFileName(?string $fileName): self
|
||||
{
|
||||
$obj = clone $this;
|
||||
|
||||
$obj->fileName = $fileName;
|
||||
|
||||
return $obj;
|
||||
@@ -162,7 +157,6 @@ class Params
|
||||
public function withName(?string $name): self
|
||||
{
|
||||
$obj = clone $this;
|
||||
|
||||
$obj->name = $name;
|
||||
|
||||
return $obj;
|
||||
@@ -171,19 +165,25 @@ class Params
|
||||
public function withSearchParams(?SearchParams $searchParams): self
|
||||
{
|
||||
$obj = clone $this;
|
||||
|
||||
$obj->searchParams = $searchParams;
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
public function withParam(string $name, mixed $value): self
|
||||
{
|
||||
$obj = clone $this;
|
||||
$obj->params[$name] = $value;
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ?string[] $fieldList
|
||||
*/
|
||||
public function withFieldList(?array $fieldList): self
|
||||
{
|
||||
$obj = clone $this;
|
||||
|
||||
$obj->fieldList = $fieldList;
|
||||
|
||||
return $obj;
|
||||
@@ -195,7 +195,6 @@ class Params
|
||||
public function withAttributeList(?array $attributeList): self
|
||||
{
|
||||
$obj = clone $this;
|
||||
|
||||
$obj->attributeList = $attributeList;
|
||||
|
||||
return $obj;
|
||||
@@ -204,7 +203,6 @@ class Params
|
||||
public function withAccessControl(bool $applyAccessControl = true): self
|
||||
{
|
||||
$obj = clone $this;
|
||||
|
||||
$obj->applyAccessControl = $applyAccessControl;
|
||||
|
||||
return $obj;
|
||||
@@ -274,6 +272,32 @@ class Params
|
||||
return $this->fieldList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a parameter list.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getParamList(): array
|
||||
{
|
||||
return array_keys($this->params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a parameter value.
|
||||
*/
|
||||
public function getParam(string $name): mixed
|
||||
{
|
||||
return $this->params[$name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has a parameter.
|
||||
*/
|
||||
public function hasParam(string $name): bool
|
||||
{
|
||||
return array_key_exists($name, $this->params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether all fields should be exported.
|
||||
*/
|
||||
|
||||
@@ -43,6 +43,8 @@ class Params
|
||||
private ?array $fieldList = null;
|
||||
private ?string $name = null;
|
||||
private ?string $entityType = null;
|
||||
/** @var array<string, mixed> */
|
||||
private array $params = [];
|
||||
|
||||
/**
|
||||
* @param string[] $attributeList
|
||||
@@ -93,6 +95,14 @@ class Params
|
||||
return $obj;
|
||||
}
|
||||
|
||||
public function withParam(string $name, mixed $value): self
|
||||
{
|
||||
$obj = clone $this;
|
||||
$obj->params[$name] = $value;
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* An export file name.
|
||||
*/
|
||||
@@ -140,4 +150,12 @@ class Params
|
||||
|
||||
return $this->entityType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a parameter value.
|
||||
*/
|
||||
public function getParam(string $name): mixed
|
||||
{
|
||||
return $this->params[$name] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,18 +31,14 @@ namespace Espo\Tools\Export;
|
||||
|
||||
use Espo\Core\Exceptions\ForbiddenSilent;
|
||||
use Espo\Core\Exceptions\NotFoundSilent;
|
||||
|
||||
use Espo\Core\Acl;
|
||||
use Espo\Core\Acl\Table;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Core\Job\JobSchedulerFactory;
|
||||
use Espo\Core\Job\Job\Data as JobData;
|
||||
|
||||
use Espo\Tools\Export\Jobs\Process;
|
||||
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use Espo\Entities\Export as ExportEntity;
|
||||
use Espo\Entities\User;
|
||||
|
||||
@@ -50,37 +46,15 @@ use stdClass;
|
||||
|
||||
class Service
|
||||
{
|
||||
private Factory $factory;
|
||||
|
||||
private Config $config;
|
||||
|
||||
private Acl $acl;
|
||||
|
||||
private User $user;
|
||||
|
||||
private Metadata $metadata;
|
||||
|
||||
private EntityManager $entityManager;
|
||||
|
||||
private JobSchedulerFactory $jobSchedulerFactory;
|
||||
|
||||
public function __construct(
|
||||
Factory $factory,
|
||||
Config $config,
|
||||
Acl $acl,
|
||||
User $user,
|
||||
Metadata $metadata,
|
||||
EntityManager $entityManager,
|
||||
JobSchedulerFactory $jobSchedulerFactory
|
||||
) {
|
||||
$this->factory = $factory;
|
||||
$this->config = $config;
|
||||
$this->acl = $acl;
|
||||
$this->user = $user;
|
||||
$this->metadata = $metadata;
|
||||
$this->entityManager = $entityManager;
|
||||
$this->jobSchedulerFactory = $jobSchedulerFactory;
|
||||
}
|
||||
private Factory $factory,
|
||||
private Config $config,
|
||||
private Acl $acl,
|
||||
private User $user,
|
||||
private Metadata $metadata,
|
||||
private EntityManager $entityManager,
|
||||
private JobSchedulerFactory $jobSchedulerFactory
|
||||
) {}
|
||||
|
||||
public function process(Params $params, ServiceParams $serviceParams): ServiceResult
|
||||
{
|
||||
@@ -121,8 +95,8 @@ class Service
|
||||
|
||||
public function getStatusData(string $id): stdClass
|
||||
{
|
||||
/** @var ExportEntity|null $entity */
|
||||
$entity = $this->entityManager->getEntity(ExportEntity::ENTITY_TYPE, $id);
|
||||
/** @var ?ExportEntity $entity */
|
||||
$entity = $this->entityManager->getEntityById(ExportEntity::ENTITY_TYPE, $id);
|
||||
|
||||
if (!$entity) {
|
||||
throw new NotFoundSilent();
|
||||
@@ -140,8 +114,8 @@ class Service
|
||||
|
||||
public function subscribeToNotificationOnSuccess(string $id): void
|
||||
{
|
||||
/** @var ExportEntity|null $entity */
|
||||
$entity = $this->entityManager->getEntity(ExportEntity::ENTITY_TYPE, $id);
|
||||
/** @var ?ExportEntity $entity */
|
||||
$entity = $this->entityManager->getEntityById(ExportEntity::ENTITY_TYPE, $id);
|
||||
|
||||
if (!$entity) {
|
||||
throw new NotFoundSilent();
|
||||
|
||||
@@ -1,5 +1 @@
|
||||
<div class="panel panel-default no-side-margin">
|
||||
<div class="panel-body">
|
||||
<div class="record">{{{record}}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="record no-side-margin">{{{record}}}</div>
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<div class="cell form-group" data-name="format">
|
||||
<label class="control-label" data-name="format">{{translate 'format' category='fields' scope='Export'}}</label>
|
||||
<div class="field" data-name="format">{{{formatField}}}</div>
|
||||
</div>
|
||||
|
||||
<div class="cell form-group" data-name="exportAllFields">
|
||||
<label class="control-label" data-name="exportAllFields">{{translate 'exportAllFields' category='fields' scope='Export'}}</label>
|
||||
<div class="field" data-name="exportAllFields">{{{exportAllFieldsField}}}</div>
|
||||
</div>
|
||||
|
||||
<div class="cell form-group" data-name="fieldList">
|
||||
<label class="control-label" data-name="fieldList">{{translate 'fieldList' category='fields' scope='Export'}}</label>
|
||||
<div class="field" data-name="fieldList">{{{fieldListField}}}</div>
|
||||
</div>
|
||||
@@ -248,7 +248,10 @@ define('model', [], function () {
|
||||
/**
|
||||
* Set defs.
|
||||
*
|
||||
* @param {Object} defs
|
||||
* @param {{
|
||||
* fields?: Object.<string, *>,
|
||||
* links?: Object.<string, *>,
|
||||
* }} defs
|
||||
*/
|
||||
setDefs: function (defs) {
|
||||
this.defs = defs || {};
|
||||
|
||||
@@ -70,7 +70,7 @@ define('views/export/modals/export', ['views/modal', 'model'], function (Dep, Mo
|
||||
this.model.set('exportAllFields', true);
|
||||
}
|
||||
|
||||
var formatList =
|
||||
let formatList =
|
||||
this.getMetadata().get(['scopes', this.scope, 'exportFormatList']) ||
|
||||
this.getMetadata().get('app.export.formatList');
|
||||
|
||||
@@ -80,52 +80,80 @@ define('views/export/modals/export', ['views/modal', 'model'], function (Dep, Mo
|
||||
scope: this.scope,
|
||||
model: this.model,
|
||||
el: this.getSelector() + ' .record',
|
||||
formatList: formatList,
|
||||
});
|
||||
},
|
||||
|
||||
getRecordView: function () {
|
||||
return this.getView('record');
|
||||
},
|
||||
|
||||
actionExport: function () {
|
||||
var data = this.getView('record').fetch();
|
||||
let recordView = this.getRecordView();
|
||||
|
||||
let data = recordView.fetch();
|
||||
|
||||
this.model.set(data);
|
||||
|
||||
if (this.getView('record').validate()) {
|
||||
if (recordView.validate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var returnData = {
|
||||
let returnData = {
|
||||
exportAllFields: data.exportAllFields,
|
||||
format: data.format,
|
||||
};
|
||||
|
||||
if (!data.exportAllFields) {
|
||||
var attributeList = [];
|
||||
let attributeList = [];
|
||||
|
||||
data.fieldList.forEach(function (item) {
|
||||
data.fieldList.forEach(item => {
|
||||
if (item === 'id') {
|
||||
attributeList.push('id');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var type = this.getMetadata().get(['entityDefs', this.scope, 'fields', item, 'type']);
|
||||
let type = this.getMetadata().get(['entityDefs', this.scope, 'fields', item, 'type']);
|
||||
|
||||
if (type) {
|
||||
this.getFieldManager().getAttributeList(type, item).forEach(function (attribute) {
|
||||
attributeList.push(attribute);
|
||||
}, this);
|
||||
this.getFieldManager().getAttributeList(type, item)
|
||||
.forEach(attribute => {
|
||||
attributeList.push(attribute);
|
||||
});
|
||||
}
|
||||
|
||||
if (~item.indexOf('_')) {
|
||||
attributeList.push(item);
|
||||
}
|
||||
}, this);
|
||||
});
|
||||
|
||||
returnData.attributeList = attributeList;
|
||||
returnData.fieldList = data.fieldList;
|
||||
}
|
||||
|
||||
returnData.params = {};
|
||||
|
||||
recordView.getFormatParamList(data.format).forEach(param => {
|
||||
let name = recordView.modifyParamName(data.format, param);
|
||||
|
||||
let fieldView = recordView.getFieldView(name);
|
||||
|
||||
if (!fieldView || fieldView.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.getFieldManager()
|
||||
.getActualAttributeList(fieldView.type, param)
|
||||
.forEach(subParam => {
|
||||
let name = recordView.modifyParamName(data.format, subParam);
|
||||
|
||||
returnData.params[subParam] = data[name];
|
||||
});
|
||||
});
|
||||
|
||||
this.trigger('proceed', returnData);
|
||||
this.close();
|
||||
},
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,51 +26,226 @@
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
define('views/export/record/record', 'views/record/base', function (Dep) {
|
||||
define('views/export/record/record', ['views/record/edit-for-modal'], function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
/**
|
||||
* @class
|
||||
* @name Class
|
||||
* @memberOf module:views/export/record/record
|
||||
* @extends module:views/record/edit-for-modal.Class
|
||||
*/
|
||||
return Dep.extend(/** @lends module:views/export/record/record.Class# */{
|
||||
|
||||
template: 'export/record/record',
|
||||
/**
|
||||
* @type {string[]},
|
||||
*/
|
||||
formatList: null,
|
||||
|
||||
/**
|
||||
* @type {Object.<string, string[]>},
|
||||
*/
|
||||
customParams: null,
|
||||
|
||||
setup: function () {
|
||||
Dep.prototype.setup.call(this);
|
||||
},
|
||||
|
||||
setupBeforeFinal: function () {
|
||||
this.formatList = this.options.formatList;
|
||||
this.scope = this.options.scope;
|
||||
|
||||
var fieldList = this.getFieldManager().getEntityTypeFieldList(this.scope);
|
||||
let fieldsData = this.getExportFieldsData();
|
||||
|
||||
var forbiddenFieldList = this.getAcl().getScopeForbiddenFieldList(this.scope);
|
||||
this.setupExportFieldDefs(fieldsData);
|
||||
this.setupExportLayout(fieldsData);
|
||||
this.setupExportDynamicLogic();
|
||||
|
||||
fieldList = fieldList.filter(function (item) {
|
||||
this.controlFormatField();
|
||||
this.listenTo(this.model, 'change:format', () => this.controlFormatField());
|
||||
|
||||
this.controlAllFields();
|
||||
this.listenTo(this.model, 'change:exportAllFields', () => this.controlAllFields());
|
||||
|
||||
Dep.prototype.setupBeforeFinal.call(this);
|
||||
},
|
||||
|
||||
setupExportFieldDefs: function (fieldsData) {
|
||||
let fieldDefs = {
|
||||
format: {
|
||||
type: 'enum',
|
||||
options: this.formatList,
|
||||
},
|
||||
fieldList: {
|
||||
type: 'multiEnum',
|
||||
options: fieldsData.list,
|
||||
required: true,
|
||||
},
|
||||
exportAllFields: {
|
||||
type: 'bool',
|
||||
},
|
||||
};
|
||||
|
||||
this.customParams = {};
|
||||
|
||||
this.formatList.forEach(format => {
|
||||
let fields = this.getFormatParamsDefs(format).fields || {};
|
||||
|
||||
this.customParams[format] = [];
|
||||
|
||||
for (let name in fields) {
|
||||
let newName = this.modifyParamName(format, name);
|
||||
|
||||
this.customParams[format].push(name);
|
||||
|
||||
fieldDefs[newName] = Espo.Utils.cloneDeep(fields[name]);
|
||||
}
|
||||
});
|
||||
|
||||
this.model.setDefs({fields: fieldDefs});
|
||||
},
|
||||
|
||||
setupExportLayout: function (fieldsData) {
|
||||
this.detailLayout = [];
|
||||
|
||||
let mainPanel = {
|
||||
rows: [
|
||||
[
|
||||
{name: 'format'},
|
||||
false
|
||||
],
|
||||
[
|
||||
{name: 'exportAllFields'},
|
||||
false
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'fieldList',
|
||||
options: {
|
||||
translatedOptions: fieldsData.translations,
|
||||
},
|
||||
}
|
||||
],
|
||||
]
|
||||
};
|
||||
|
||||
this.detailLayout.push(mainPanel);
|
||||
|
||||
this.formatList.forEach(format => {
|
||||
let 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 => {
|
||||
let defs = this.getFormatParamsDefs(format).dynamicLogic || {};
|
||||
|
||||
this.customParams[format].forEach(param => {
|
||||
let logic = defs[param] || {};
|
||||
|
||||
if (!logic.visible) {
|
||||
logic.visible = {};
|
||||
}
|
||||
|
||||
if (!logic.visible.conditionGroup) {
|
||||
logic.visible.conditionGroup = [];
|
||||
}
|
||||
|
||||
logic.visible.conditionGroup.push({
|
||||
type: 'equals',
|
||||
attribute: 'format',
|
||||
value: format,
|
||||
});
|
||||
|
||||
let newName = this.modifyParamName(format, param);
|
||||
|
||||
this.dynamicLogicDefs.fields[newName] = logic;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} format
|
||||
* @return {string[]}
|
||||
*/
|
||||
getFormatParamList: function (format) {
|
||||
return Object.keys(this.getFormatParamsDefs(format).fields || {});
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @return {Object.<string, *>}
|
||||
*/
|
||||
getFormatParamsDefs: function (format) {
|
||||
let defs = this.getMetadata().get(['app', 'export', 'formatDefs', format]) || {};
|
||||
|
||||
return Espo.Utils.cloneDeep(defs.params || {});
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} format
|
||||
* @param {string} name
|
||||
* @return {string}
|
||||
*/
|
||||
modifyParamName: function (format, name) {
|
||||
return format + Espo.Utils.upperCaseFirst(name);
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {{
|
||||
* translations: Object.<string, string>,
|
||||
* list: string[]
|
||||
* }}
|
||||
*/
|
||||
getExportFieldsData: function () {
|
||||
let fieldList = this.getFieldManager().getEntityTypeFieldList(this.scope);
|
||||
let forbiddenFieldList = this.getAcl().getScopeForbiddenFieldList(this.scope);
|
||||
|
||||
fieldList = fieldList.filter(item => {
|
||||
return !~forbiddenFieldList.indexOf(item);
|
||||
}, this);
|
||||
});
|
||||
|
||||
fieldList = fieldList.filter(item => {
|
||||
let defs = this.getMetadata().get(['entityDefs', this.scope, 'fields', item]) || {};
|
||||
|
||||
fieldList = fieldList.filter(function (item) {
|
||||
var defs = this.getMetadata().get(['entityDefs', this.scope, 'fields', item]) || {};
|
||||
|
||||
if (defs.disabled) return;
|
||||
if (defs.exportDisabled) return;
|
||||
if (defs.type === 'map') return;
|
||||
if (
|
||||
defs.disabled ||
|
||||
defs.exportDisabled ||
|
||||
defs.type === 'map'
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true;
|
||||
}, this);
|
||||
});
|
||||
|
||||
this.getLanguage().sortFieldList(this.scope, fieldList);
|
||||
|
||||
fieldList.unshift('id');
|
||||
|
||||
var translatedOptions = {};
|
||||
let fieldListTranslations = {};
|
||||
|
||||
fieldList.forEach(function (item) {
|
||||
translatedOptions[item] = this.getLanguage().translate(item, 'fields', this.scope);
|
||||
}, this);
|
||||
fieldList.forEach(item => {
|
||||
fieldListTranslations[item] = this.getLanguage().translate(item, 'fields', this.scope);
|
||||
});
|
||||
|
||||
this.createField('exportAllFields', 'views/fields/bool', {});
|
||||
let setFieldList = this.model.get('fieldList') || [];
|
||||
|
||||
var setFieldList = this.model.get('fieldList') || [];
|
||||
|
||||
setFieldList.forEach(function (item) {
|
||||
setFieldList.forEach(item => {
|
||||
if (~fieldList.indexOf(item)) {
|
||||
return;
|
||||
}
|
||||
@@ -79,49 +254,52 @@ define('views/export/record/record', 'views/record/base', function (Dep) {
|
||||
return;
|
||||
}
|
||||
|
||||
var arr = item.split('_');
|
||||
let arr = item.split('_');
|
||||
|
||||
fieldList.push(item);
|
||||
|
||||
var foreignScope = this.getMetadata().get(['entityDefs', this.scope, 'links', arr[0], 'entity']);
|
||||
let foreignScope = this.getMetadata().get(['entityDefs', this.scope, 'links', arr[0], 'entity']);
|
||||
|
||||
if (!foreignScope) {
|
||||
return;
|
||||
}
|
||||
|
||||
translatedOptions[item] = this.getLanguage().translate(arr[0], 'links', this.scope) + '.' +
|
||||
fieldListTranslations[item] = this.getLanguage().translate(arr[0], 'links', this.scope) + '.' +
|
||||
this.getLanguage().translate(arr[1], 'fields', foreignScope);
|
||||
}, this);
|
||||
|
||||
|
||||
this.createField('fieldList', 'views/fields/multi-enum', {
|
||||
required: true,
|
||||
translatedOptions: translatedOptions,
|
||||
options: fieldList,
|
||||
});
|
||||
|
||||
var formatList =
|
||||
this.getMetadata().get(['scopes', this.scope, 'exportFormatList']) ||
|
||||
this.getMetadata().get('app.export.formatList');
|
||||
|
||||
this.createField('format', 'views/fields/enum', {
|
||||
options: formatList
|
||||
});
|
||||
|
||||
this.controlAllFields();
|
||||
|
||||
this.listenTo(this.model, 'change:exportAllFields', function () {
|
||||
this.controlAllFields();
|
||||
}, this);
|
||||
return {
|
||||
list: fieldList,
|
||||
translations: fieldListTranslations,
|
||||
};
|
||||
},
|
||||
|
||||
controlAllFields: function () {
|
||||
if (!this.model.get('exportAllFields')) {
|
||||
this.showField('fieldList');
|
||||
} else {
|
||||
this.hideField('fieldList');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.hideField('fieldList');
|
||||
},
|
||||
|
||||
controlFormatField: function () {
|
||||
let 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);
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1148,6 +1148,7 @@ function (Dep, MassActionHelper, ExportHelper, RecordModal) {
|
||||
|
||||
data.idle = idle;
|
||||
data.format = dialogData.format;
|
||||
data.params = dialogData.params;
|
||||
|
||||
Espo.Ui.notify(this.translate('pleaseWait', 'messages'));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user