diff --git a/application/Espo/Core/SelectManagers/Base.php b/application/Espo/Core/SelectManagers/Base.php index 94b2ccd3b2..68a3f1d187 100644 --- a/application/Espo/Core/SelectManagers/Base.php +++ b/application/Espo/Core/SelectManagers/Base.php @@ -122,7 +122,7 @@ class Base } } - protected function order($sortBy, $asc, &$result) + protected function order($sortBy, $desc = false, &$result) { if (!empty($sortBy)) { $result['orderBy'] = $sortBy; @@ -137,7 +137,7 @@ class Base if ($this->getMetadata()->get(['entityDefs', $this->getEntityType(), 'fields', $sortBy, 'isSorted'])) { $list = asort($list); } - if (!$asc) { + if ($desc) { $list = array_reverse($list); } $result['orderBy'] = 'LIST:' . $sortBy . ':' . implode(',', $list); @@ -145,7 +145,7 @@ class Base } } } - if ($asc) { + if (!$desc) { $result['order'] = 'ASC'; } else { $result['order'] = 'DESC'; @@ -629,6 +629,11 @@ class Base return $result; } + public function buildSelectParams(array $params, $withAcl = false, $checkWherePermission = false) + { + return $this->getSelectParams($params, $withAcl, $checkWherePermission); + } + public function getSelectParams(array $params, $withAcl = false, $checkWherePermission = false) { $result = array(); @@ -638,7 +643,7 @@ class Base if (!array_key_exists('asc', $params)) { $params['asc'] = true; } - $this->order($params['sortBy'], $params['asc'], $result); + $this->order($params['sortBy'], !$params['asc'], $result); } if (!isset($params['offset'])) { @@ -1056,10 +1061,10 @@ class Base return $part; } - public function applyOrder($sortBy, $asc, &$result) + public function applyOrder($sortBy, $desc, &$result) { $this->prepareResult($result); - $this->order($sortBy, $asc, $result); + $this->order($sortBy, $desc, $result); } public function applyLimit($offset, $maxSize, &$result) diff --git a/application/Espo/Modules/Crm/Controllers/KnowledgeBaseArticle.php b/application/Espo/Modules/Crm/Controllers/KnowledgeBaseArticle.php index 89f117dfc6..9ee73eb760 100644 --- a/application/Espo/Modules/Crm/Controllers/KnowledgeBaseArticle.php +++ b/application/Espo/Modules/Crm/Controllers/KnowledgeBaseArticle.php @@ -40,4 +40,34 @@ class KnowledgeBaseArticle extends \Espo\Core\Controllers\Record return $this->getRecordService()->getCopiedAttachments($id); } + + public function postActionMoveUp($params, $data, $request) + { + if (empty($data['id'])) { + throw new BadRequest(); + } + $where = null; + if (!empty($data['where'])) { + $where = $data['where']; + } + + $this->getRecordService()->moveUp($data['id'], $where); + + return true; + } + + public function postActionMoveDown($params, $data, $request) + { + if (empty($data['id'])) { + throw new BadRequest(); + } + $where = null; + if (!empty($data['where'])) { + $where = $data['where']; + } + + $this->getRecordService()->moveDown($data['id'], $where); + + return true; + } } diff --git a/application/Espo/Modules/Crm/Resources/i18n/en_US/KnowledgeBaseArticle.json b/application/Espo/Modules/Crm/Resources/i18n/en_US/KnowledgeBaseArticle.json index d14ecb559e..e010f6ad00 100644 --- a/application/Espo/Modules/Crm/Resources/i18n/en_US/KnowledgeBaseArticle.json +++ b/application/Espo/Modules/Crm/Resources/i18n/en_US/KnowledgeBaseArticle.json @@ -2,7 +2,9 @@ "labels": { "Create KnowledgeBaseArticle": "Create Article", "Any": "Any", - "Send in Email": "Send in Email" + "Send in Email": "Send in Email", + "Move Up": "Move Up", + "Move Down": "Move Down" }, "fields": { "name": "Name", diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/KnowledgeBaseArticle.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/KnowledgeBaseArticle.json index 625f53656c..32598d1e0b 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/KnowledgeBaseArticle.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/KnowledgeBaseArticle.json @@ -6,7 +6,8 @@ "recordViews":{ "editQuick":"crm:views/knowledge-base-article/record/edit-quick", "detailQuick":"crm:views/knowledge-base-article/record/detail-quick", - "detail":"crm:views/knowledge-base-article/record/detail" + "detail":"crm:views/knowledge-base-article/record/detail", + "list":"crm:views/knowledge-base-article/record/list" }, "modalViews": { "select": "crm:views/knowledge-base-article/modals/select-records" diff --git a/application/Espo/Modules/Crm/Services/KnowledgeBaseArticle.php b/application/Espo/Modules/Crm/Services/KnowledgeBaseArticle.php index f30da7450d..3b94acbd58 100644 --- a/application/Espo/Modules/Crm/Services/KnowledgeBaseArticle.php +++ b/application/Espo/Modules/Crm/Services/KnowledgeBaseArticle.php @@ -31,6 +31,10 @@ namespace Espo\Modules\Crm\Services; use \Espo\ORM\Entity; +use \Espo\Core\Exceptions\Forbidden; +use \Espo\Core\Exceptions\NotFound; +use \Espo\Core\Exceptions\Error; + class KnowledgeBaseArticle extends \Espo\Services\Record { public function getCopiedAttachments($id, $parentType = null, $parentId = null) @@ -82,5 +86,72 @@ class KnowledgeBaseArticle extends \Espo\Services\Record 'names' => $names ); } + + + public function moveUp($id, $where = null) + { + $entity = $this->getEntityManager()->getEntity('KnowledgeBaseArticle', $id); + if (!$entity) throw new NotFound(); + if (!$this->getAcl()->check($entity, 'edit')) throw new Forbidden(); + + $currentIndex = $entity->get('order'); + + if (!is_int($currentIndex)) throw new Error(); + + if (!$where) { + $where = array(); + } + $selectManager = $this->getSelectManager(); + $selectParams = $selectManager->buildSelectParams($where, true, true); + + $selectParams['whereClause'][] = array( + 'order<' => $currentIndex + ); + + $selectManager->applyOrder('order', true, $selectParams); + + $previousEntity = $this->getRepository()->findOne($selectParams); + + if (!$previousEntity) return; + + $entity->set('order', $previousEntity->get('order')); + $previousEntity->set('order', $currentIndex); + + $this->getEntityManager()->saveEntity($entity); + $this->getEntityManager()->saveEntity($previousEntity); + } + + public function moveDown($id, $where = null) + { + $entity = $this->getEntityManager()->getEntity('KnowledgeBaseArticle', $id); + if (!$entity) throw new NotFound(); + if (!$this->getAcl()->check($entity, 'edit')) throw new Forbidden(); + + $currentIndex = $entity->get('order'); + + if (!is_int($currentIndex)) throw new Error(); + + if (!$where) { + $where = array(); + } + $selectManager = $this->getSelectManager(); + $selectParams = $selectManager->buildSelectParams($where, true, true); + + $selectParams['whereClause'][] = array( + 'order>' => $currentIndex + ); + + $selectManager->applyOrder('order', false, $selectParams); + + $nextEntity = $this->getRepository()->findOne($selectParams); + + if (!$nextEntity) return; + + $entity->set('order', $nextEntity->get('order')); + $nextEntity->set('order', $currentIndex); + + $this->getEntityManager()->saveEntity($entity); + $this->getEntityManager()->saveEntity($nextEntity); + } } diff --git a/client/modules/crm/src/views/knowledge-base-article/record/list.js b/client/modules/crm/src/views/knowledge-base-article/record/list.js new file mode 100644 index 0000000000..e2fda0adf1 --- /dev/null +++ b/client/modules/crm/src/views/knowledge-base-article/record/list.js @@ -0,0 +1,67 @@ +/************************************************************************ + * 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/. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU General Public License version 3. + * + * In accordance with Section 7(b) of the GNU General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. + ************************************************************************/ + +Espo.define('crm:views/knowledge-base-article/record/list', 'views/record/list', function (Dep) { + + return Dep.extend({ + + rowActionsView: 'crm:views/knowledge-base-article/record/row-actions/default', + + actionMoveUp: function (data) { + var model = this.collection.get(data.id); + if (!model) return; + + var index = this.collection.indexOf(model); + if (index === 0) return; + + this.ajaxPostRequest('knowledgeBaseArticle/action/moveUp', { + id: model.id, + where: this.collection.getWhere() + }).then(function () { + this.collection.fetch(); + }.bind(this)); + }, + + actionMoveDown: function (data) { + var model = this.collection.get(data.id); + if (!model) return; + + var index = this.collection.indexOf(model); + if ((index === this.collection.length - 1) && (this.collection.length === this.collection.total)) return; + + this.ajaxPostRequest('knowledgeBaseArticle/action/moveDown', { + id: model.id, + where: this.collection.getWhere() + }).then(function () { + this.collection.fetch(); + }.bind(this)); + }, + + }); +}); + diff --git a/client/modules/crm/src/views/knowledge-base-article/record/row-actions/default.js b/client/modules/crm/src/views/knowledge-base-article/record/row-actions/default.js new file mode 100644 index 0000000000..41c84c0d26 --- /dev/null +++ b/client/modules/crm/src/views/knowledge-base-article/record/row-actions/default.js @@ -0,0 +1,57 @@ +/************************************************************************ + * 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/. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU General Public License version 3. + * + * In accordance with Section 7(b) of the GNU General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. + ************************************************************************/ + +Espo.define('crm:views/knowledge-base-article/record/row-actions/default', 'views/record/row-actions/default', function (Dep) { + + return Dep.extend({ + + getActionList: function () { + var actionList = Dep.prototype.getActionList.call(this); + + if (this.options.acl.edit && this.model.collection && this.model.collection.sortBy == 'order' && this.model.collection.asc) { + actionList.push({ + action: 'moveUp', + label: 'Move Up', + data: { + id: this.model.id + } + }); + actionList.push({ + action: 'moveDown', + label: 'Move Down', + data: { + id: this.model.id + } + }); + } + + return actionList; + } + }); + +});