From 1e67fe69e1550342addcc0b1fdccf67e48aa8070 Mon Sep 17 00:00:00 2001 From: yuri Date: Tue, 28 Apr 2015 17:53:31 +0300 Subject: [PATCH] dev --- application/Espo/Core/Controllers/Record.php | 4 +- .../Espo/Core/Controllers/RecordTree.php | 60 +++++++++ application/Espo/Core/Entities/TreeItem.php | 43 ++++++ application/Espo/Services/RecordTree.php | 74 +++++++++++ .../Custom/Controllers/ArticleCategory.php | 7 + .../Espo/Custom/Entities/ArticleCategory.php | 8 ++ .../Custom/Repositories/ArticleCategory.php | 5 + .../Espo/Custom/Services/ArticleCategory.php | 7 + .../res/layout-types/list-row-expanded.tpl | 8 +- .../client/src/controllers/record-tree.js | 42 ++++++ frontend/client/src/views/list-tree.js | 36 +++++ frontend/client/src/views/list.js | 6 +- frontend/client/src/views/record/list-tree.js | 125 ++++++++++++++++++ frontend/client/src/views/record/list.js | 10 +- 14 files changed, 423 insertions(+), 12 deletions(-) create mode 100644 application/Espo/Core/Controllers/RecordTree.php create mode 100644 application/Espo/Core/Entities/TreeItem.php create mode 100644 application/Espo/Services/RecordTree.php create mode 100644 custom/Espo/Custom/Controllers/ArticleCategory.php create mode 100644 custom/Espo/Custom/Entities/ArticleCategory.php create mode 100644 custom/Espo/Custom/Repositories/ArticleCategory.php create mode 100644 custom/Espo/Custom/Services/ArticleCategory.php create mode 100644 frontend/client/src/controllers/record-tree.js create mode 100644 frontend/client/src/views/list-tree.js create mode 100644 frontend/client/src/views/record/list-tree.js diff --git a/application/Espo/Core/Controllers/Record.php b/application/Espo/Core/Controllers/Record.php index 87b0cda083..fa677aab51 100644 --- a/application/Espo/Core/Controllers/Record.php +++ b/application/Espo/Core/Controllers/Record.php @@ -34,6 +34,8 @@ class Record extends Base public static $defaultAction = 'list'; + protected $defaultRecordServiceName = 'Record'; + protected function getEntityManager() { return $this->getContainer()->get('entityManager'); @@ -48,7 +50,7 @@ class Record extends Base if ($this->getServiceFactory()->checkExists($name)) { $service = $this->getServiceFactory()->create($name); } else { - $service = $this->getServiceFactory()->create('Record'); + $service = $this->getServiceFactory()->create($this->defaultRecordServiceName); $service->setEntityName($name); } diff --git a/application/Espo/Core/Controllers/RecordTree.php b/application/Espo/Core/Controllers/RecordTree.php new file mode 100644 index 0000000000..73a2e4875e --- /dev/null +++ b/application/Espo/Core/Controllers/RecordTree.php @@ -0,0 +1,60 @@ +getAcl()->check($this->name, 'read')) { + throw new Forbidden(); + } + + $where = $request->get('where'); + $parentId = $request->get('parentId'); + $asc = $request->get('asc') === 'true'; + $sortBy = $request->get('sortBy'); + + $collection = $this->getRecordService()->getTree($parentId, array( + 'where' => $where, + 'asc' => $asc, + 'sortBy' => $sortBy, + )); + return array( + 'list' => $collection->toArray(), + 'path' => $this->getRecordService()->getTreeItemPath($parentId) + ); + } +} + diff --git a/application/Espo/Core/Entities/TreeItem.php b/application/Espo/Core/Entities/TreeItem.php new file mode 100644 index 0000000000..0f70bc7847 --- /dev/null +++ b/application/Espo/Core/Entities/TreeItem.php @@ -0,0 +1,43 @@ +get('childList'); + if (is_null($childList)) { + $data['childList'] = null; + } else { + $arr = []; + foreach ($childList as $entity) { + $arr[] = $entity->toArray(); + } + $data['childList'] = $arr; + } + return $data; + } +} + diff --git a/application/Espo/Services/RecordTree.php b/application/Espo/Services/RecordTree.php new file mode 100644 index 0000000000..9d4ee28972 --- /dev/null +++ b/application/Espo/Services/RecordTree.php @@ -0,0 +1,74 @@ +getSelectParams($params); + $selectParams['whereClause'][] = array( + 'parentId' => $parentId + ); + + + $collection = $this->getRepository()->find($selectParams); + foreach ($collection as $entity) { + $childList = $this->getTree($entity->id, $params, $level + 1); + $entity->set('childList', $childList); + + } + return $collection; + } + + public function getTreeItemPath($parentId = null) + { + $arr = []; + while (1) { + if (empty($parentId)) { + break; + } + $parent = $this->getEntityManager()->getEntity($this->entityType, $parentId); + if ($parent) { + $parentId = $parent->get('parentId'); + array_unshift($arr, $parent->id); + } else { + $parentId = null; + } + } + return $arr; + } +} + diff --git a/custom/Espo/Custom/Controllers/ArticleCategory.php b/custom/Espo/Custom/Controllers/ArticleCategory.php new file mode 100644 index 0000000000..4b3ebfd916 --- /dev/null +++ b/custom/Espo/Custom/Controllers/ArticleCategory.php @@ -0,0 +1,7 @@ + +
  • <% if (layout.right) { %>
    {{{<%= layout.right.name %>}}} -
    + <% } %> <% _.each(layout.rows, function (row, key) { %>
    @@ -10,7 +10,7 @@ <% var tag = 'tag' in defs ? defs.tag : false; if (tag) { - print( '<' + tag); + print( '<' + tag); if ('id' in defs) { print(' id="'+defs.id+'"'); } @@ -18,7 +18,7 @@ print(' class="'+defs.class+'"'); }; print('>'); - } + } %>{{{<%= defs.name %>}}}<% if (tag) { print( ''); diff --git a/frontend/client/src/controllers/record-tree.js b/frontend/client/src/controllers/record-tree.js new file mode 100644 index 0000000000..624e25b691 --- /dev/null +++ b/frontend/client/src/controllers/record-tree.js @@ -0,0 +1,42 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko + * Website: http://www.espocrm.com + * + * EspoCRM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EspoCRM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EspoCRM. If not, see http://www.gnu.org/licenses/. + ************************************************************************/ +Espo.define('Controllers.RecordTree', 'Controllers.Record', function (Dep) { + + return Dep.extend({ + + defaultAction: 'listTree', + + beforeListTree: function () { + this.handleCheckAccess('read'); + }, + + listTree: function (options) { + this.getCollection(function (collection) { + this.main(this.getViewName('listTree'), { + scope: this.name, + collection: collection + }); + }); + } + + }); + +}); diff --git a/frontend/client/src/views/list-tree.js b/frontend/client/src/views/list-tree.js new file mode 100644 index 0000000000..4e5296d6d5 --- /dev/null +++ b/frontend/client/src/views/list-tree.js @@ -0,0 +1,36 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko + * Website: http://www.espocrm.com + * + * EspoCRM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EspoCRM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EspoCRM. If not, see http://www.gnu.org/licenses/. + ************************************************************************/ + +Espo.define('Views.ListTree', 'Views.List', function (Dep) { + + return Dep.extend({ + + searchPanel: false, + + createButton: false, + + getRecordViewName: function () { + return this.getMetadata().get('clientDefs.' + this.scope + '.recordViews.listTree') || 'Record.ListTree'; + } + + }); +}); + diff --git a/frontend/client/src/views/list.js b/frontend/client/src/views/list.js index 026dcbca1b..fb90f3bf79 100644 --- a/frontend/client/src/views/list.js +++ b/frontend/client/src/views/list.js @@ -113,10 +113,14 @@ Espo.define('Views.List', ['Views.Main', 'SearchManager'], function (Dep, Search } }, + getRecordViewName: function () { + return this.getMetadata().get('clientDefs.' + this.scope + '.recordViews.list') || 'Record.List'; + }, + afterRender: function () { this.notify('Loading...'); - var listViewName = this.getMetadata().get('clientDefs.' + this.scope + '.recordViews.list') || 'Record.List'; + var listViewName = this.getRecordViewName(); this.listenToOnce(this.collection, 'sync', function () { this.createView('list', listViewName, { diff --git a/frontend/client/src/views/record/list-tree.js b/frontend/client/src/views/record/list-tree.js new file mode 100644 index 0000000000..99c241dbf1 --- /dev/null +++ b/frontend/client/src/views/record/list-tree.js @@ -0,0 +1,125 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko + * Website: http://www.espocrm.com + * + * EspoCRM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EspoCRM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EspoCRM. If not, see http://www.gnu.org/licenses/. + ************************************************************************/ + +Espo.define('Views.Record.ListTree', 'Views.Record.List', function (Dep) { + + return Dep.extend({ + + template: 'record.list-tree', + + checkboxes: false, + + selectable: false, + + rowActionsView: false, + + _internalLayoutType: 'list-row-expanded', + + presentationType: 'tree', + + header: false, + + listContainerEl: '.list > ul', + + _loadListLayout: function (callback) { + var type = this.type + 'Expanded'; + this._helper.layoutManager.get(this.collection.name, type, function (listLayout) { + callback(listLayout); + }); + }, + + _convertLayout: function (listLayout, model) { + model = model || this.collection.model.prototype; + + var layout = { + rows: [], + right: false, + }; + + for (var i in listLayout.rows) { + var row = listLayout.rows[i]; + var layoutRow = []; + for (var j in row) { + + var e = row[j]; + var type = e.type || model.getFieldType(e.name) || 'base'; + + var item = { + name: e.name, + view: e.view || model.getFieldParam(e.name, 'view') || this.getFieldManager().getViewName(type), + options: { + defs: { + name: e.name, + params: e.params || {} + }, + mode: 'list' + } + }; + if (e.link) { + item.options.mode = 'listLink'; + } + layoutRow.push(item); + } + layout.rows.push(layoutRow); + } + + if ('right' in listLayout) { + if (listLayout.right != false) { + layout.right = { + name: listLayout.right.name || 'right', + view: listLayout.right.view, + options: { + defs: { + params: { + width: listLayout.right.width || '7%' + } + } + } + }; + } + } else { + if (this.rowActionsView) { + layout.right = this.getRowActionsDefs(); + } + } + return layout; + }, + + getRowSelector: function (id) { + return 'li[data-id="' + id + '"]'; + }, + + getItemEl: function (model, item) { + return this.options.el + ' li[data-id="' + model.id + '"] span.cell-' + item.name; + }, + + prepareInterbalLayout: function (internalLayout, model) { + var rows = internalLayout.rows || []; + rows.forEach(function (row) { + row.forEach(function (col) { + col.el = this.getItemEl(model, col); + }, this); + }, this); + }, + + }); +}); + diff --git a/frontend/client/src/views/record/list.js b/frontend/client/src/views/record/list.js index cf552a5cc3..f0339016bf 100644 --- a/frontend/client/src/views/record/list.js +++ b/frontend/client/src/views/record/list.js @@ -740,9 +740,7 @@ Espo.define('Views.Record.List', 'View', function (Dep) { this.checkedList = []; this.rows = []; - if (this.collection.length > 0) { - var i = 0; var c = !this.pagination ? 1 : 2; var func = function () { @@ -756,10 +754,10 @@ Espo.define('Views.Record.List', 'View', function (Dep) { this.wait(true); this.getInternalLayout(function (internalLayout) { - var count = this.collection.models.length; + var modelList = this.collection.models; + var count = modelList.length; var built = 0; - for (var i in this.collection.models) { - var model = this.collection.models[i]; + modelList.forEach(function (model) { this.buildRow(i, model, function () { built++; if (built == count) { @@ -767,7 +765,7 @@ Espo.define('Views.Record.List', 'View', function (Dep) { this.wait(false); } }.bind(this)); - } + }, this); }.bind(this)); if (this.pagination) {