From e6948aba2e46a49a4cc8c8487ecf64f1a7bdd209 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Mon, 4 Aug 2014 12:19:09 +0300 Subject: [PATCH 01/26] mark all read --- application/Espo/Controllers/Notification.php | 8 +++++++- .../Espo/Resources/i18n/en_US/Global.json | 3 ++- application/Espo/Services/Notification.php | 8 ++++++++ .../res/templates/notifications/panel.tpl | 2 +- .../client/src/views/notifications/badge.js | 19 +++++++++++++++---- .../client/src/views/notifications/panel.js | 11 +++++++++++ 6 files changed, 44 insertions(+), 7 deletions(-) diff --git a/application/Espo/Controllers/Notification.php b/application/Espo/Controllers/Notification.php index 3c2f82379b..03811feadf 100644 --- a/application/Espo/Controllers/Notification.php +++ b/application/Espo/Controllers/Notification.php @@ -54,7 +54,13 @@ class Notification extends \Espo\Core\Controllers\Base public function actionNotReadCount() { $userId = $this->getUser()->id; - return $this->getService('Notification')->getNotReadCount($userId); + return $this->getService('Notification')->getNotReadCount($userId); + } + + public function actionMarkAllRead($params, $data, $request) + { + $userId = $this->getUser()->id; + return $this->getService('Notification')->markAllRead($userId); } } diff --git a/application/Espo/Resources/i18n/en_US/Global.json b/application/Espo/Resources/i18n/en_US/Global.json index 844cce3b28..c00b12156f 100644 --- a/application/Espo/Resources/i18n/en_US/Global.json +++ b/application/Espo/Resources/i18n/en_US/Global.json @@ -114,7 +114,8 @@ "Administration": "Administration", "Run Import": "Run Import", "Duplicate": "Duplicate", - "Notifications": "Notifications" + "Notifications": "Notifications", + "Mark all read": "Mark all read" }, "messages": { "notModified": "You have not modified the record", diff --git a/application/Espo/Services/Notification.php b/application/Espo/Services/Notification.php index 842616d114..fb282af174 100644 --- a/application/Espo/Services/Notification.php +++ b/application/Espo/Services/Notification.php @@ -84,6 +84,14 @@ class Notification extends \Espo\Core\Services\Base ))->count(); } + public function markAllRead($userId) + { + $pdo = $this->getEntityManager()->getPDO(); + $sql = "UPDATE notification SET `read` = 1 WHERE user_id = ".$pdo->quote($userId)." AND `read` = 0"; + $pdo->prepare($sql)->execute(); + return true; + } + public function getList($userId, array $params = array()) { $searchParams = array(); diff --git a/frontend/client/res/templates/notifications/panel.tpl b/frontend/client/res/templates/notifications/panel.tpl index e8907a370f..3e8c537a30 100644 --- a/frontend/client/res/templates/notifications/panel.tpl +++ b/frontend/client/res/templates/notifications/panel.tpl @@ -1,5 +1,5 @@
-
{{translate 'Notifications'}}
+
{{translate 'Mark all read'}}{{translate 'Notifications'}}
{{translate 'Loading...'}} diff --git a/frontend/client/src/views/notifications/badge.js b/frontend/client/src/views/notifications/badge.js index 0e50a756c8..01ef51a690 100644 --- a/frontend/client/src/views/notifications/badge.js +++ b/frontend/client/src/views/notifications/badge.js @@ -49,14 +49,22 @@ Espo.define('Views.Notifications.Badge', 'View', function (Dep) { this.checkUpdates(); }, + showNotRead: function (count) { + this.$icon.addClass('warning'); + this.$badge.attr('title', this.translate('New notifications') + ': ' + count); + }, + + hideNotRead: function () { + this.$icon.removeClass('warning'); + this.$badge.attr('title', ''); + }, + checkUpdates: function () { $.ajax('Notification/action/notReadCount').done(function (count) { if (count) { - this.$icon.addClass('warning'); - this.$badge.attr('title', this.translate('New notifications') + ': ' + count); + this.showNotRead(count); } else { - this.$icon.removeClass('warning'); - this.$badge.attr('title', ''); + this.hideNotRead(); } }.bind(this)); @@ -82,6 +90,9 @@ Espo.define('Views.Notifications.Badge', 'View', function (Dep) { el: '#notifications-panel', }, function (view) { view.render(); + this.listenTo(view, 'all-read', function () { + this.hideNotRead(); + }, this); }.bind(this)); $document = $(document); diff --git a/frontend/client/src/views/notifications/panel.js b/frontend/client/src/views/notifications/panel.js index 86a8a7ecdc..400fb440c1 100644 --- a/frontend/client/src/views/notifications/panel.js +++ b/frontend/client/src/views/notifications/panel.js @@ -25,6 +25,17 @@ Espo.define('Views.Notifications.Panel', 'View', function (Dep) { template: 'notifications.panel', + events: { + 'click [data-action="markAllNotificationsRead"]': function () { + $.ajax({ + url: 'Notification/action/markAllRead', + type: 'POST' + }).done(function (count) { + this.trigger('all-read'); + }.bind(this)); + }, + }, + setup: function () { this.wait(true); this.getCollectionFactory().create('Notification', function (collection) { From e3a3547a54cf629f7df22091e1c8d4ff6b332d68 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Mon, 4 Aug 2014 12:36:51 +0300 Subject: [PATCH 02/26] prevent error if field name is empty in layout --- frontend/client/src/views/record/detail.js | 4 ++++ frontend/client/src/views/record/list.js | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/frontend/client/src/views/record/detail.js b/frontend/client/src/views/record/detail.js index c2b28ba06e..69c6f4fb88 100644 --- a/frontend/client/src/views/record/detail.js +++ b/frontend/client/src/views/record/detail.js @@ -547,6 +547,10 @@ Espo.define('Views.Record.Detail', 'View', function (Dep) { for (var j in simplifiedLayout[p].rows[i]) { var cellDefs = simplifiedLayout[p].rows[i][j]; + + if (!cellDefs.name) { + continue; + } if (cellDefs == false) { row.push(false); diff --git a/frontend/client/src/views/record/list.js b/frontend/client/src/views/record/list.js index 3605f148bf..030773266d 100644 --- a/frontend/client/src/views/record/list.js +++ b/frontend/client/src/views/record/list.js @@ -433,7 +433,10 @@ Espo.define('Views.Record.List', 'View', function (Dep) { for (var i in listLayout) { var col = listLayout[i]; - var type = col.type || model.getFieldType(col.name) || 'base'; + var type = col.type || model.getFieldType(col.name) || 'base'; + if (!col.name) { + continue; + } var item = { name: col.name, view: col.view || model.getFieldParam(col.name, 'view') || this.getFieldManager().getViewName(type), From 1cfad615c0bbed7e5b1067b1400c0bca6f93ff98 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Mon, 4 Aug 2014 13:35:35 +0300 Subject: [PATCH 03/26] not team restricion for admin --- application/Espo/Core/SelectManagers/Base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/Espo/Core/SelectManagers/Base.php b/application/Espo/Core/SelectManagers/Base.php index 74c73a6fff..57710ffdbf 100644 --- a/application/Espo/Core/SelectManagers/Base.php +++ b/application/Espo/Core/SelectManagers/Base.php @@ -176,7 +176,7 @@ class Base } $result['whereClause']['assignedUserId'] = $this->user->id; } - if ($this->acl->checkReadOnlyTeam($this->entityName)) { + if (!$this->user->isAdmin() && $this->acl->checkReadOnlyTeam($this->entityName)) { if (!array_key_exists('whereClause', $result)) { $result['whereClause'] = array(); } From b8476d733558add18637c4ed97a9031494da24a4 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Mon, 4 Aug 2014 15:23:41 +0300 Subject: [PATCH 04/26] fix import --- frontend/client/src/views/import/step1.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/client/src/views/import/step1.js b/frontend/client/src/views/import/step1.js index ba68d0e980..1ef747f861 100644 --- a/frontend/client/src/views/import/step1.js +++ b/frontend/client/src/views/import/step1.js @@ -81,7 +81,7 @@ Espo.define('Views.Import.Step1', 'View', function (Dep) { afterRender: function () { this.setupFormData(); - if (this.getParentView().fileContents) { + if (this.getParentView() && this.getParentView().fileContents) { this.setFileIsLoaded(); this.preview(); } @@ -148,7 +148,7 @@ Espo.define('Views.Import.Step1', 'View', function (Dep) { }, setFileIsLoaded: function () { - $('button[data-action="next"]').removeClass('hidden'); + this.$el.find('button[data-action="next"]').removeClass('hidden'); }, preview: function () { From 488717c6a14284d2c236f9c400895241f2eecceb Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Mon, 4 Aug 2014 17:05:24 +0300 Subject: [PATCH 05/26] dashlet changes --- .../Crm/Resources/i18n/en_US/Global.json | 2 + .../Resources/metadata/dashlets/Calendar.json | 2 +- .../Resources/metadata/dashlets/Calls.json | 1 + .../Resources/metadata/dashlets/Cases.json | 2 +- .../Resources/metadata/dashlets/Leads.json | 2 +- .../Resources/metadata/dashlets/Meetings.json | 1 + .../metadata/dashlets/Opportunities.json | 2 +- .../dashlets/OpportunitiesByLeadSource.json | 2 +- .../dashlets/OpportunitiesByStage.json | 2 +- .../metadata/dashlets/SalesByMonth.json | 2 +- .../metadata/dashlets/SalesPipeline.json | 2 +- .../Resources/metadata/dashlets/Tasks.json | 2 +- .../modules/crm/src/views/dashlets/calls.js | 81 +++++++++++++++++++ .../crm/src/views/dashlets/meetings.js | 81 +++++++++++++++++++ frontend/client/src/views/dashlet.js | 6 +- 15 files changed, 178 insertions(+), 12 deletions(-) create mode 100644 application/Espo/Modules/Crm/Resources/metadata/dashlets/Calls.json create mode 100644 application/Espo/Modules/Crm/Resources/metadata/dashlets/Meetings.json create mode 100644 frontend/client/modules/crm/src/views/dashlets/calls.js create mode 100644 frontend/client/modules/crm/src/views/dashlets/meetings.js diff --git a/application/Espo/Modules/Crm/Resources/i18n/en_US/Global.json b/application/Espo/Modules/Crm/Resources/i18n/en_US/Global.json index 4e8e1d3355..d224ea2e32 100644 --- a/application/Espo/Modules/Crm/Resources/i18n/en_US/Global.json +++ b/application/Espo/Modules/Crm/Resources/i18n/en_US/Global.json @@ -31,6 +31,8 @@ "Tasks": "My Tasks", "Cases": "My Cases", "Calendar": "Calendar", + "Calls": "My Calls", + "Meetings": "My Meetings", "OpportunitiesByStage": "Opportunities by Stage", "OpportunitiesByLeadSource": "Opportunities by Lead Source", "SalesByMonth": "Sales by Month", diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calendar.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calendar.json index 35cd5348b4..70b0e1c73d 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calendar.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calendar.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.Calendar"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calls.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calls.json new file mode 100644 index 0000000000..78a2f1b939 --- /dev/null +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Calls.json @@ -0,0 +1 @@ +{"view":"Crm:Dashlets.Calls"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json index 35cd5348b4..f518fbab1e 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.Cases"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Leads.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Leads.json index 35cd5348b4..595862a3cf 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Leads.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Leads.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.Leads"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Meetings.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Meetings.json new file mode 100644 index 0000000000..17838c2e56 --- /dev/null +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Meetings.json @@ -0,0 +1 @@ +{"view":"Crm:Dashlets.Meetings"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Opportunities.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Opportunities.json index 35cd5348b4..524c074c7a 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Opportunities.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Opportunities.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.Opportunities"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByLeadSource.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByLeadSource.json index 35cd5348b4..7b8d988fd7 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByLeadSource.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByLeadSource.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.OpportunitiesByLeadSource"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByStage.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByStage.json index 35cd5348b4..3e75625357 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByStage.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/OpportunitiesByStage.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.OpportunitiesByStage"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesByMonth.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesByMonth.json index 35cd5348b4..cff85c9eb0 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesByMonth.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesByMonth.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.SalesByMonth"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesPipeline.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesPipeline.json index 35cd5348b4..f312aa2101 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesPipeline.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/SalesPipeline.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.SalesPipeline"} diff --git a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Tasks.json b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Tasks.json index 35cd5348b4..c9d63fc12a 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/dashlets/Tasks.json +++ b/application/Espo/Modules/Crm/Resources/metadata/dashlets/Tasks.json @@ -1 +1 @@ -{"module":"Crm"} +{"view":"Crm:Dashlets.Tasks"} diff --git a/frontend/client/modules/crm/src/views/dashlets/calls.js b/frontend/client/modules/crm/src/views/dashlets/calls.js new file mode 100644 index 0000000000..20f32becd2 --- /dev/null +++ b/frontend/client/modules/crm/src/views/dashlets/calls.js @@ -0,0 +1,81 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014 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('Crm:Views.Dashlets.Calls', 'Views.Dashlets.Abstract.RecordList', function (Dep) { + + return Dep.extend({ + + name: 'Calls', + + scope: 'Call', + + defaultOptions: { + displayRecords: 5, + columnLayout: [ + { + name: 'name', + link: true, + sortable: false, + width: 40, + }, + { + name: 'status', + sortable: false, + }, + { + name: 'dateStart', + sortable: false, + } + ], + expandedLayout: { + rows: [ + [ + { + name: 'name', + link: true, + } + ], + [ + { + name: 'status' + }, + { + name: 'dateStart' + } + ] + ] + }, + searchData: { + bool: { + onlyMy: true, + }, + advanced: { + status: { + type: 'notIn', + value: ['Held', 'Not Held'] + } + } + }, + }, + + }); +}); + diff --git a/frontend/client/modules/crm/src/views/dashlets/meetings.js b/frontend/client/modules/crm/src/views/dashlets/meetings.js new file mode 100644 index 0000000000..41f21a7ea6 --- /dev/null +++ b/frontend/client/modules/crm/src/views/dashlets/meetings.js @@ -0,0 +1,81 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014 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('Crm:Views.Dashlets.Meetings', 'Views.Dashlets.Abstract.RecordList', function (Dep) { + + return Dep.extend({ + + name: 'Meetings', + + scope: 'Meeting', + + defaultOptions: { + displayRecords: 5, + columnLayout: [ + { + name: 'name', + link: true, + sortable: false, + width: 40, + }, + { + name: 'status', + sortable: false, + }, + { + name: 'dateStart', + sortable: false, + } + ], + expandedLayout: { + rows: [ + [ + { + name: 'name', + link: true, + } + ], + [ + { + name: 'status' + }, + { + name: 'dateStart' + } + ] + ] + }, + searchData: { + bool: { + onlyMy: true, + }, + advanced: { + status: { + type: 'notIn', + value: ['Held', 'Not Held'] + } + } + }, + }, + + }); +}); + diff --git a/frontend/client/src/views/dashlet.js b/frontend/client/src/views/dashlet.js index 5fa99f3337..46e5c02f9b 100644 --- a/frontend/client/src/views/dashlet.js +++ b/frontend/client/src/views/dashlet.js @@ -55,9 +55,9 @@ Espo.define('Views.Dashlet', 'View', function (Dep) { }; var bodySelector = '#dashlet-' + this.id + ' .dashlet-body'; - var module = this.getMetadata().get('dashlets.' + this.name + '.module'); - - this.createView('body', Espo.Utils.composeClassName(module, this.name, 'Dashlets'), {el: bodySelector, id: this.id}); + var view = this.getMetadata().get('dashlets.' + this.name + '.view') || 'Dashlets.' + this.name; + + this.createView('body', view, {el: bodySelector, id: this.id}); }, refresh: function () { From 26188879b6bcfd3dc6d2423642db89e50f662229 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Tue, 5 Aug 2014 10:49:29 +0300 Subject: [PATCH 06/26] fix client acl --- application/Espo/Controllers/Layout.php | 5 ++++ frontend/client/src/controller.js | 23 ++++++++++++------- frontend/client/src/controllers/admin.js | 10 ++++---- .../client/src/controllers/preferences.js | 7 +----- frontend/client/src/controllers/record.js | 10 ++++++++ 5 files changed, 36 insertions(+), 19 deletions(-) diff --git a/application/Espo/Controllers/Layout.php b/application/Espo/Controllers/Layout.php index 76e65e2079..a14eaf149f 100644 --- a/application/Espo/Controllers/Layout.php +++ b/application/Espo/Controllers/Layout.php @@ -25,6 +25,7 @@ namespace Espo\Controllers; use Espo\Core\Utils as Utils; use \Espo\Core\Exceptions\NotFound; use \Espo\Core\Exceptions\Error; +use \Espo\Core\Exceptions\Forbidden; class Layout extends \Espo\Core\Controllers\Base { @@ -39,6 +40,10 @@ class Layout extends \Espo\Core\Controllers\Base public function actionUpdate($params, $data) { + if (!$this->getUser()->isAdmin()) { + throw new Forbidden(); + } + $result = $this->getContainer()->get('layout')->set($data, $params['scope'], $params['name']); if ($result === false) { diff --git a/frontend/client/src/controller.js b/frontend/client/src/controller.js index 400a153905..5185092bad 100644 --- a/frontend/client/src/controller.js +++ b/frontend/client/src/controller.js @@ -116,27 +116,34 @@ _.extend(Espo.Controller.prototype, { }, checkAccess: function (action) { - if (this.getUser().isAdmin()) { - return true; + return true; + }, + + handleAccessGlobal: function () { + if (!this.checkAccessGlobal()) { + throw new Espo.Exceptions.AccessDenied("Denied access to action '" + this.name + "#" + action + "'"); } - if (this.getAcl().check(this.name, action)) { - return true; - } - return false; }, + checkAccessGlobal: function () { + return true; + }, + handleCheckAccess: function (action) { if (!this.checkAccess(action)) { - throw new Espo.Exceptions.AccessDenied("Acl has denied access to action '" + this.name + "#" + action + "'"); + throw new Espo.Exceptions.AccessDenied("Denied access to action '" + this.name + "#" + action + "'"); } }, doAction: function (action, options) { + this.handleAccessGlobal(); + action = action || this.defaultAction; var method = action; if (!(method in this)) { throw new Espo.Exceptions.NotFound("Action '" + this.name + "#" + action + "' is not found"); - } + } + var preMethod = 'before' + Espo.Utils.upperCaseFirst(method); var postMethod = 'after' + Espo.Utils.upperCaseFirst(method); diff --git a/frontend/client/src/controllers/admin.js b/frontend/client/src/controllers/admin.js index 2c41e60634..0c4b53114d 100644 --- a/frontend/client/src/controllers/admin.js +++ b/frontend/client/src/controllers/admin.js @@ -20,14 +20,14 @@ ************************************************************************/ Espo.define('Controllers.Admin', 'Controller', function (Dep) { - return Dep.extend({ + return Dep.extend({ - checkAccess: function () { + checkAccessGlobal: function () { if (this.getUser().isAdmin()) { return true; } return false; - }, + }, index: function () { this.main('Admin.Index', null); @@ -36,7 +36,7 @@ Espo.define('Controllers.Admin', 'Controller', function (Dep) { layouts: function (options) { var scope = options.scope || null; var type = options.type || null; - + this.main('Admin.Layouts.Index', {scope: scope, type: type}); }, @@ -49,7 +49,7 @@ Espo.define('Controllers.Admin', 'Controller', function (Dep) { upgrade: function (options) { this.main('Admin.Upgrade.Index'); - }, + }, getSettingsModel: function () { var model = this.getConfig().clone(); diff --git a/frontend/client/src/controllers/preferences.js b/frontend/client/src/controllers/preferences.js index dc5a596f7e..6532bb9453 100644 --- a/frontend/client/src/controllers/preferences.js +++ b/frontend/client/src/controllers/preferences.js @@ -33,12 +33,7 @@ Espo.define('Controllers.Preferences', 'Controllers.Record', function (Dep) { }, checkAccess: function (action) { - if (this.getUser().isAdmin()) { - return true; - } - if (action != 'own') { - return false; - } + return true; }, own: function () { diff --git a/frontend/client/src/controllers/record.js b/frontend/client/src/controllers/record.js index 7b826590d1..933a4b9bbc 100644 --- a/frontend/client/src/controllers/record.js +++ b/frontend/client/src/controllers/record.js @@ -25,6 +25,16 @@ Espo.define('Controllers.Record', 'Controller', function (Dep) { viewMap: null, defaultAction: 'list', + + checkAccess: function (action) { + if (this.getUser().isAdmin()) { + return true; + } + if (this.getAcl().check(this.name, action)) { + return true; + } + return false; + }, initialize: function () { this.viewMap = this.viewMap || {}; From 3e9c7056b017d79b20ab29178376d918d92dddda Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Tue, 5 Aug 2014 10:54:19 +0300 Subject: [PATCH 07/26] improve mark all read --- frontend/client/src/views/notifications/badge.js | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/client/src/views/notifications/badge.js b/frontend/client/src/views/notifications/badge.js index 01ef51a690..4c1c09029d 100644 --- a/frontend/client/src/views/notifications/badge.js +++ b/frontend/client/src/views/notifications/badge.js @@ -92,6 +92,7 @@ Espo.define('Views.Notifications.Badge', 'View', function (Dep) { view.render(); this.listenTo(view, 'all-read', function () { this.hideNotRead(); + this.$el.find('.badge-circle-warning').remove(); }, this); }.bind(this)); From dd5fabdfa4ef55ee4b22bed8e1586c2e24c692ea Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Tue, 5 Aug 2014 11:44:10 +0300 Subject: [PATCH 08/26] contacts select in meetings --- .../Resources/metadata/entityDefs/Call.json | 3 +- .../metadata/entityDefs/Meeting.json | 3 +- .../crm/src/views/meeting/fields/contacts.js | 40 +++++++++++++++++++ .../client/src/views/fields/link-parent.js | 6 ++- .../client/src/views/record/panels/side.js | 3 +- 5 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 frontend/client/modules/crm/src/views/meeting/fields/contacts.js diff --git a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Call.json b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Call.json index 8e58a5235d..6106cc7bbc 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Call.json +++ b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Call.json @@ -52,7 +52,8 @@ }, "contacts": { "type": "linkMultiple", - "disabled": true + "disabled": true, + "view": "Crm:Meeting.Fields.Contacts" }, "leads": { "type": "linkMultiple", diff --git a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Meeting.json b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Meeting.json index 2d6b57a976..b0a6e1b7aa 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Meeting.json +++ b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Meeting.json @@ -47,7 +47,8 @@ }, "contacts": { "type": "linkMultiple", - "disabled": true + "disabled": true, + "view": "Crm:Meeting.Fields.Contacts" }, "leads": { "type": "linkMultiple", diff --git a/frontend/client/modules/crm/src/views/meeting/fields/contacts.js b/frontend/client/modules/crm/src/views/meeting/fields/contacts.js new file mode 100644 index 0000000000..7f903419b5 --- /dev/null +++ b/frontend/client/modules/crm/src/views/meeting/fields/contacts.js @@ -0,0 +1,40 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014 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('Crm:Views.Meeting.Fields.Contacts', 'Views.Fields.LinkMultiple', function (Dep) { + + return Dep.extend({ + + getSelectFilters: function () { + if (this.model.get('parentType') == 'Account' && this.model.get('parentId')) { + return { + 'account': { + type: 'equals', + field: 'accountId', + value: this.model.get('parentId'), + valueName: this.model.get('parentName'), + } + }; + } + }, + }); + +}); diff --git a/frontend/client/src/views/fields/link-parent.js b/frontend/client/src/views/fields/link-parent.js index fbb9f669ab..55b0852ec9 100644 --- a/frontend/client/src/views/fields/link-parent.js +++ b/frontend/client/src/views/fields/link-parent.js @@ -74,7 +74,7 @@ Espo.define('Views.Fields.LinkParent', 'Views.Fields.Base', function (Dep) { if (this.mode != 'list') { this.addActionHandler('selectLink', function () { - Espo.Ui.notify('Loading...'); + this.notify('Loading...'); this.createView('dialog', 'Modals.SelectRecords', { scope: this.foreignScope, createButton: this.mode != 'search' @@ -84,12 +84,14 @@ Espo.define('Views.Fields.LinkParent', 'Views.Fields.Base', function (Dep) { dialog.once('select', function (model) { self.$elementName.val(model.get('name')); self.$elementId.val(model.get('id')); + self.trigger('change'); }); }); }); this.addActionHandler('clearLink', function () { this.$elementName.val(''); - this.$elementId.val(''); + this.$elementId.val(''); + this.trigger('change'); }); this.events['change select[name="' + this.typeName + '"]'] = function (e) { diff --git a/frontend/client/src/views/record/panels/side.js b/frontend/client/src/views/record/panels/side.js index 949ccbdf9a..94c0c5eaf9 100644 --- a/frontend/client/src/views/record/panels/side.js +++ b/frontend/client/src/views/record/panels/side.js @@ -62,7 +62,8 @@ Espo.define('Views.Record.Panels.Side', 'View', function (Dep) { createField: function (field, readOnly) { var type = this.model.getFieldType(field) || 'base'; - this.createView(field, 'Fields.' + Espo.Utils.upperCaseFirst(type), { + var viewName = this.model.getFieldParam(field, 'view') || this.getFieldManager().getViewName(type); + this.createView(field, viewName, { model: this.model, el: this.options.el + ' .field-' + field, defs: { From c1cfd75bd6eaf75e91cfeadab12d4b0e78c5dd8e Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Tue, 5 Aug 2014 14:38:47 +0300 Subject: [PATCH 09/26] fix notice --- application/Espo/Modules/Crm/Services/Lead.php | 2 ++ frontend/index.html | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/application/Espo/Modules/Crm/Services/Lead.php b/application/Espo/Modules/Crm/Services/Lead.php index e2e6f0c329..2128af3cbd 100644 --- a/application/Espo/Modules/Crm/Services/Lead.php +++ b/application/Espo/Modules/Crm/Services/Lead.php @@ -25,6 +25,8 @@ namespace Espo\Modules\Crm\Services; use \Espo\Core\Exceptions\Error; use \Espo\Core\Exceptions\Forbidden; +use \Espo\ORM\Entity; + class Lead extends \Espo\Services\Record { protected function getDuplicateWhereClause(Entity $entity) diff --git a/frontend/index.html b/frontend/index.html index 41af0689b4..b37dac368f 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -70,7 +70,7 @@