From efd5ccfa96a39c3c5f52e9b52efc2e69dc5c2b70 Mon Sep 17 00:00:00 2001 From: yuri Date: Mon, 18 Jun 2018 13:23:35 +0300 Subject: [PATCH] list view select only attributes from layout --- application/Espo/Core/Controllers/Record.php | 4 ++ application/Espo/Services/Record.php | 62 +++++++++++++++++-- client/lib/bull.js | 4 +- .../crm/src/views/record/panels/tasks.js | 31 +++++----- .../views/dashlets/abstract/record-list.js | 34 +++++----- client/src/views/list.js | 19 +++--- client/src/views/modals/select-records.js | 41 ++++++------ client/src/views/record/kanban.js | 3 +- client/src/views/record/list-expanded.js | 20 +++++- client/src/views/record/list-tree.js | 3 +- client/src/views/record/list.js | 42 ++++++++++++- .../src/views/record/panels/relationship.js | 31 +++++----- 12 files changed, 209 insertions(+), 85 deletions(-) diff --git a/application/Espo/Core/Controllers/Record.php b/application/Espo/Core/Controllers/Record.php index 561ebdd517..66bb924fff 100644 --- a/application/Espo/Core/Controllers/Record.php +++ b/application/Espo/Core/Controllers/Record.php @@ -213,6 +213,10 @@ class Record extends Base if ($request->get('filterList')) { $params['filterList'] = $request->get('filterList'); } + + if ($request->get('select')) { + $params['select'] = explode(',', $request->get('select')); + } } public function actionListLinked($params, $data, $request) diff --git a/application/Espo/Services/Record.php b/application/Espo/Services/Record.php index 9ed81420c2..00449de553 100644 --- a/application/Espo/Services/Record.php +++ b/application/Espo/Services/Record.php @@ -99,6 +99,8 @@ class Record extends \Espo\Core\Services\Base protected $selectAttributeList = null; + protected $mandatorySelectAttributeList = []; + const MAX_SELECT_TEXT_ATTRIBUTE_LENGTH = 5000; const FOLLOWERS_LIMIT = 4; @@ -902,7 +904,7 @@ class Record extends \Espo\Core\Services\Base $selectParams['maxTextColumnsLength'] = $this->getMaxSelectTextAttributeLength(); - $selectAttributeList = $this->getSelectAttributeList(); + $selectAttributeList = $this->getSelectAttributeList($params); if ($selectAttributeList) { $selectParams['select'] = $selectAttributeList; } else { @@ -959,7 +961,7 @@ class Record extends \Espo\Core\Services\Base $selectParams['maxTextColumnsLength'] = $this->getMaxSelectTextAttributeLength(); - $selectAttributeList = $this->getSelectAttributeList(); + $selectAttributeList = $this->getSelectAttributeList($params); if ($selectAttributeList) { $selectParams['select'] = $selectAttributeList; } else { @@ -1110,7 +1112,7 @@ class Record extends \Espo\Core\Services\Base $selectParams['maxTextColumnsLength'] = $recordService->getMaxSelectTextAttributeLength(); - $selectAttributeList = $recordService->getSelectAttributeList(); + $selectAttributeList = $recordService->getSelectAttributeList($params); if ($selectAttributeList) { $selectParams['select'] = $selectAttributeList; } else { @@ -2114,9 +2116,57 @@ class Record extends \Espo\Core\Services\Base return $this->getFieldManagerUtil()->getFieldByTypeList($this->entityType, $type); } - public function getSelectAttributeList() + public function getSelectAttributeList($params) { - return $this->selectAttributeList; + if ($this->selectAttributeList) { + return $this->selectAttributeList; + } + + $seed = $this->getEntityManager()->getEntity($this->getEntityType()); + + if (array_key_exists('select', $params)) { + $passedAttributeList = $params['select']; + } else { + $passedAttributeList = null; + } + + if ($passedAttributeList) { + $attributeList = []; + if (!in_array('id', $passedAttributeList)) { + $attributeList[] = 'id'; + } + $aclAttributeList = ['assignedUserId', 'createdById']; + + foreach ($aclAttributeList as $attribute) { + if (!in_array($attribute, $passedAttributeList) && $seed->hasAttribute($attribute)) { + $attributeList[] = $attribute; + } + } + + foreach ($passedAttributeList as $attribute) { + if ($seed->hasAttribute($attribute)) { + $attributeList[] = $attribute; + } + } + + if (!empty($params['sortBy'])) { + $sortByField = $params['sortBy']; + $sortByFieldType = $this->getMetadata()->get(['entityDefs', $this->getEntityType(), 'fields', $sortByField, 'type']); + if ($sortByFieldType === 'currency') { + $attributeList[] = $sortByField . 'Converted'; + } + + } + + foreach ($this->mandatorySelectAttributeList as $attribute) { + if ($seed->hasAttribute($attribute)) { + $attributeList[] = $attribute; + } + } + + return $attributeList; + } + + return null; } } - diff --git a/client/lib/bull.js b/client/lib/bull.js index 2a3e16d518..06585cf3f3 100644 --- a/client/lib/bull.js +++ b/client/lib/bull.js @@ -784,13 +784,13 @@ var Bull = Bull || {}; options.el = this.getSelector() + ' [data-view="'+key+'"]'; } this._factory.create(viewName, options, function (view) { - if (this._isRendered) { + if (this._isRendered || options.setViewBeforeCallback) { this.setView(key, view); } if (typeof callback === 'function') { callback.call(context, view); } - if (!this._isRendered) { + if (!this._isRendered && !options.setViewBeforeCallback) { this.setView(key, view); } }.bind(this)); diff --git a/client/modules/crm/src/views/record/panels/tasks.js b/client/modules/crm/src/views/record/panels/tasks.js index 58b37c7343..df799e7951 100644 --- a/client/modules/crm/src/views/record/panels/tasks.js +++ b/client/modules/crm/src/views/record/panels/tasks.js @@ -148,20 +148,23 @@ Espo.define('crm:views/record/panels/tasks', 'views/record/panels/relationship', var rowActionsView = 'crm:views/record/row-actions/tasks'; - this.listenToOnce(this.collection, 'sync', function () { - this.createView('list', 'views/record/list-expanded', { - el: this.getSelector() + ' > .list-container', - pagination: false, - type: 'listRelationship', - rowActionsView: rowActionsView, - checkboxes: false, - collection: collection, - listLayout: this.listLayout, - }, function (view) { - view.render(); - }); - }.bind(this)); - this.collection.fetch(); + this.createView('list', 'views/record/list-expanded', { + el: this.getSelector() + ' > .list-container', + pagination: false, + type: 'listRelationship', + rowActionsView: rowActionsView, + checkboxes: false, + collection: collection, + listLayout: this.listLayout, + skipBuildRows: true + }, function (view) { + view.getSelectAttributeList(function (selectAttributeList) { + if (selectAttributeList) { + this.collection.data.select = selectAttributeList.join(','); + } + this.collection.fetch(); + }.bind(this)); + }); }, this); }, diff --git a/client/src/views/dashlets/abstract/record-list.js b/client/src/views/dashlets/abstract/record-list.js index 449bdf03b5..5fe765929c 100644 --- a/client/src/views/dashlets/abstract/record-list.js +++ b/client/src/views/dashlets/abstract/record-list.js @@ -99,22 +99,24 @@ Espo.define('views/dashlets/abstract/record-list', ['views/dashlets/abstract/bas var viewName = this.listView || ((this.layoutType == 'expanded') ? this.listViewExpanded : this.listViewColumn); - this.listenToOnce(collection, 'sync', function () { - this.createView('list', viewName, { - collection: collection, - el: this.getSelector() + ' .list-container', - pagination: this.getOption('pagination') ? 'bottom' : false, - type: 'listDashlet', - rowActionsView: this.rowActionsView, - checkboxes: false, - showMore: true, - listLayout: this.getOption(this.layoutType + 'Layout') - }, function (view) { - view.render(); - }); - }, this); - - collection.fetch(); + this.createView('list', viewName, { + collection: collection, + el: this.getSelector() + ' .list-container', + pagination: this.getOption('pagination') ? 'bottom' : false, + type: 'listDashlet', + rowActionsView: this.rowActionsView, + checkboxes: false, + showMore: true, + listLayout: this.getOption(this.layoutType + 'Layout'), + skipBuildRows: true + }, function (view) { + view.getSelectAttributeList(function (selectAttributeList) { + if (selectAttributeList) { + collection.data.select = selectAttributeList.join(','); + } + collection.fetch(); + }.bind(this)); + }); }, this); }, diff --git a/client/src/views/list.js b/client/src/views/list.js index 392b69c1e5..d048f4faa0 100644 --- a/client/src/views/list.js +++ b/client/src/views/list.js @@ -300,9 +300,7 @@ Espo.define('views/list', ['views/main', 'search-manager'], function (Dep, Searc this.createListRecordView(false); } else { Espo.Ui.notify(this.translate('loading', 'messages')); - this.collection.fetch().then(function () { - this.createListRecordView(); - }.bind(this)); + this.createListRecordView(true); } }, @@ -312,7 +310,8 @@ Espo.define('views/list', ['views/main', 'search-manager'], function (Dep, Searc var o = { collection: this.collection, el: this.options.el + ' .list-container', - scope: this.scope + scope: this.scope, + skipBuildRows: true }; this.optionsToPass.forEach(function (option) { o[option] = this.options[option]; @@ -328,8 +327,6 @@ Espo.define('views/list', ['views/main', 'search-manager'], function (Dep, Searc return; } - view.render(); - this.listenToOnce(view, 'after:render', function () { if (!this.hasParentView()) { view.undelegateEvents(); @@ -343,10 +340,16 @@ Espo.define('views/list', ['views/main', 'search-manager'], function (Dep, Searc this.getStorage().set('listSorting', this.collection.name, obj); }, this); } + if (fetch) { - setTimeout(function () { + view.getSelectAttributeList(function (selectAttributeList) { + if (selectAttributeList) { + this.collection.data.select = selectAttributeList.join(','); + } this.collection.fetch(); - }.bind(this), 2000); + }.bind(this)); + } else { + view.render(); } }); }, diff --git a/client/src/views/modals/select-records.js b/client/src/views/modals/select-records.js index 5d2551e959..428dfd11d4 100644 --- a/client/src/views/modals/select-records.js +++ b/client/src/views/modals/select-records.js @@ -180,26 +180,31 @@ Espo.define('views/modals/select-records', ['views/modal', 'search-manager'], fu this.getMetadata().get('clientDefs.' + this.scope + '.recordViews.list') || 'views/record/list'; - this.listenToOnce(this.collection, 'sync', function () { - this.createView('list', viewName, { - collection: this.collection, - el: this.containerSelector + ' .list-container', - selectable: true, - checkboxes: this.multiple, - massActionsDisabled: true, - rowActionsView: false, - layoutName: 'listSmall', - searchManager: this.searchManager, - checkAllResultDisabled: !this.massRelateEnabled, - buttonsDisabled: true - }, function (view) { - view.once('select', function (model) { - this.trigger('select', model); - this.close(); - }.bind(this)); + this.createView('list', viewName, { + collection: this.collection, + el: this.containerSelector + ' .list-container', + selectable: true, + checkboxes: this.multiple, + massActionsDisabled: true, + rowActionsView: false, + layoutName: 'listSmall', + searchManager: this.searchManager, + checkAllResultDisabled: !this.massRelateEnabled, + buttonsDisabled: true, + skipBuildRows: true + }, function (view) { + view.once('select', function (model) { + this.trigger('select', model); + this.close(); }.bind(this)); - }.bind(this)); + view.getSelectAttributeList(function (selectAttributeList) { + if (selectAttributeList) { + this.collection.data.select = selectAttributeList.join(','); + } + this.collection.fetch(); + }.bind(this)); + }); }, create: function () { diff --git a/client/src/views/record/kanban.js b/client/src/views/record/kanban.js index 3c702775e2..477de47889 100644 --- a/client/src/views/record/kanban.js +++ b/client/src/views/record/kanban.js @@ -416,7 +416,8 @@ Espo.define('views/record/kanban', ['views/record/list'], function (Dep) { el: this.getSelector() + ' .item[data-id="'+model.id+'"]', itemLayout: this.listLayout, rowActionsDisabled: this.rowActionsDisabled, - rowActionsView: this.rowActionsView + rowActionsView: this.rowActionsView, + setViewBeforeCallback: this.options.skipBuildRows && !this.isRendered() }, callback); }, diff --git a/client/src/views/record/list-expanded.js b/client/src/views/record/list-expanded.js index 8b8b59fa96..74880384b4 100644 --- a/client/src/views/record/list-expanded.js +++ b/client/src/views/record/list-expanded.js @@ -153,7 +153,23 @@ Espo.define('views/record/list-expanded', 'views/record/list', function (Dep) { } }, + fetchAttributeListFromLayout: function () { + var list = []; + if (this.listLayout.rows) { + this.listLayout.rows.forEach(function (row) { + row.forEach(function (item) { + if (!item.name) return; + var field = item.name; + var fieldType = this.getMetadata().get(['entityDefs', this.scope, 'fields', field, 'type']); + if (!fieldType) return; + this.getFieldManager().getAttributeList(fieldType, field).forEach(function (attribute) { + list.push(attribute); + }, this); + }, this); + }, this); + } + return list; + } + }); }); - - diff --git a/client/src/views/record/list-tree.js b/client/src/views/record/list-tree.js index 51319d795f..8e793f7446 100644 --- a/client/src/views/record/list-tree.js +++ b/client/src/views/record/list-tree.js @@ -180,7 +180,8 @@ Espo.define('views/record/list-tree', 'views/record/list', function (Dep) { level: this.level, isSelected: model.id == this.selectedData.id, selectedData: this.selectedData, - selectable: this.selectable + selectable: this.selectable, + setViewBeforeCallback: this.options.skipBuildRows && !this.isRendered() }, function () { built++; if (built == count) { diff --git a/client/src/views/record/list.js b/client/src/views/record/list.js index 3a243fd36e..4475b5ab49 100644 --- a/client/src/views/record/list.js +++ b/client/src/views/record/list.js @@ -805,7 +805,9 @@ Espo.define('views/record/list', 'view', function (Dep) { }, this); this.checkedList = []; - this.buildRows(); + if (!this.options.skipBuildRows) { + this.buildRows(); + } }, afterRender: function () { @@ -868,6 +870,40 @@ Espo.define('views/record/list', 'view', function (Dep) { }.bind(this)); }, + getSelectAttributeList: function (callback) { + if (this.scope == null || this.rowHasOwnLayout) { + callback(null); + return; + } + + if (this.listLayout) { + var attributeList = this.fetchAttributeListFromLayout(); + callback(attributeList); + return; + } else { + this._loadListLayout(function (listLayout) { + this.listLayout = listLayout; + var attributeList = this.fetchAttributeListFromLayout(); + callback(attributeList); + }.bind(this)); + return; + } + }, + + fetchAttributeListFromLayout: function () { + var list = []; + this.listLayout.forEach(function (item) { + if (!item.name) return; + var field = item.name; + var fieldType = this.getMetadata().get(['entityDefs', this.scope, 'fields', field, 'type']); + if (!fieldType) return; + this.getFieldManager().getAttributeList(fieldType, field).forEach(function (attribute) { + list.push(attribute); + }, this); + }, this); + return list; + }, + _getHeaderDefs: function () { var defs = []; @@ -1103,7 +1139,8 @@ Espo.define('views/record/list', 'view', function (Dep) { type: this._internalLayoutType, layout: internalLayout }, - name: this.type + '-' + model.name + name: this.type + '-' + model.name, + setViewBeforeCallback: this.options.skipBuildRows && !this.isRendered() }, callback); }.bind(this), model); }, @@ -1424,4 +1461,3 @@ Espo.define('views/record/list', 'view', function (Dep) { } }); }); - diff --git a/client/src/views/record/panels/relationship.js b/client/src/views/record/panels/relationship.js index ee9e69eeaf..17b48c65d5 100644 --- a/client/src/views/record/panels/relationship.js +++ b/client/src/views/record/panels/relationship.js @@ -186,20 +186,23 @@ Espo.define('views/record/panels/relationship', ['views/record/panels/bottom', ' var viewName = this.defs.recordListView || this.getMetadata().get('clientDefs.' + this.scope + '.recordViews.list') || 'Record.List'; this.once('after:render', function () { - collection.once('sync', function () { - this.createView('list', viewName, { - collection: collection, - layoutName: layoutName, - listLayout: listLayout, - checkboxes: false, - rowActionsView: this.defs.readOnly ? false : (this.defs.rowActionsView || this.rowActionsView), - buttonsDisabled: true, - el: this.options.el + ' .list-container', - }, function (view) { - view.render(); - }); - }, this); - collection.fetch(); + this.createView('list', viewName, { + collection: collection, + layoutName: layoutName, + listLayout: listLayout, + checkboxes: false, + rowActionsView: this.defs.readOnly ? false : (this.defs.rowActionsView || this.rowActionsView), + buttonsDisabled: true, + el: this.options.el + ' .list-container', + skipBuildRows: true + }, function (view) { + view.getSelectAttributeList(function (selectAttributeList) { + if (selectAttributeList) { + collection.data.select = selectAttributeList.join(','); + } + collection.fetch(); + }.bind(this)); + }); }, this); this.wait(false);