diff --git a/application/Espo/Core/defaults/config.php b/application/Espo/Core/defaults/config.php
index 4d8e0353c2..cf302e1177 100644
--- a/application/Espo/Core/defaults/config.php
+++ b/application/Espo/Core/defaults/config.php
@@ -87,7 +87,7 @@ return array (
'Lead',
'Opportunity',
),
- "tabList" => array("Account", "Contact", "Lead", "Opportunity", "Calendar", "Meeting", "Call", "Task", "Case", "Email", "Campaign"),
+ "tabList" => array("Account", "Contact", "Lead", "Opportunity", "Calendar", "Meeting", "Call", "Task", "Case", "Email", "Document", "Campaign"),
"quickCreateList" => array("Account", "Contact", "Lead", "Opportunity", "Meeting", "Call", "Task", "Case"),
'calendarDefaultEntity' => 'Meeting',
'disableExport' => false,
diff --git a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Call.json b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Call.json
index 179634ac1a..0a265e749e 100644
--- a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Call.json
+++ b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Call.json
@@ -140,8 +140,7 @@
"len": "36",
"default": "None"
}
- },
- "layoutRelationshipsDisabled": true
+ }
},
"contacts": {
"type": "hasMany",
@@ -153,8 +152,7 @@
"len": "36",
"default": "None"
}
- },
- "layoutRelationshipsDisabled": true
+ }
},
"leads": {
"type": "hasMany",
@@ -166,8 +164,7 @@
"len": "36",
"default": "None"
}
- },
- "layoutRelationshipsDisabled": true
+ }
},
"parent": {
"type": "belongsToParent",
diff --git a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Meeting.json b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Meeting.json
index b2d4ad19aa..02c68c1132 100644
--- a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Meeting.json
+++ b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Meeting.json
@@ -135,8 +135,7 @@
"len": "36",
"default": "None"
}
- },
- "layoutRelationshipsDisabled": true
+ }
},
"contacts": {
"type": "hasMany",
@@ -148,8 +147,7 @@
"len": "36",
"default": "None"
}
- },
- "layoutRelationshipsDisabled": true
+ }
},
"leads": {
"type": "hasMany",
@@ -161,8 +159,7 @@
"len": "36",
"default": "None"
}
- },
- "layoutRelationshipsDisabled": true
+ }
},
"parent": {
"type": "belongsToParent",
diff --git a/application/Espo/Services/Email.php b/application/Espo/Services/Email.php
index 229abe6172..e78a3069f6 100644
--- a/application/Espo/Services/Email.php
+++ b/application/Espo/Services/Email.php
@@ -26,6 +26,7 @@ use \Espo\ORM\Entity;
use \Espo\Entities;
use \Espo\Core\Exceptions\Error;
+use \Espo\Core\Exceptions\Forbidden;
class Email extends Record
{
@@ -133,7 +134,22 @@ class Email extends Record
public function getEntity($id = null)
{
- $entity = parent::getEntity($id);
+
+ $entity = $this->getRepository()->get($id);
+ if (!empty($entity) && !empty($id)) {
+ $this->loadAdditionalFields($entity);
+
+ if (!$this->getAcl()->check($entity, 'read')) {
+ $userIdList = $entity->get('usersIds');
+ if (!is_array($userIdList) || !in_array($this->getUser()->id, $userIdList)) {
+ throw new Forbidden();
+ }
+ }
+ }
+ if (!empty($entity)) {
+ $this->prepareEntityForOutput($entity);
+ }
+
if (!empty($entity) && !empty($id)) {
if ($entity->get('fromEmailAddressName')) {
diff --git a/application/Espo/Services/User.php b/application/Espo/Services/User.php
index 9bd404662f..d3d5d97ad1 100644
--- a/application/Espo/Services/User.php
+++ b/application/Espo/Services/User.php
@@ -271,7 +271,7 @@ class User extends Record
$body = $this->getLanguage()->translate('passwordChangeLinkEmailBody', 'messages', 'User');
$link = $this->getConfig()->get('siteUrl') . '?entryPoint=changePassword&id=' . $requestId;
-
+
$body = str_replace('{link}', $link, $body);
$email->set(array(
@@ -289,6 +289,9 @@ class User extends Record
if ($id == 'system') {
throw new Forbidden();
}
+ if ($id == $this->getUser()->id) {
+ throw new Forbidden();
+ }
return parent::deleteEntity($id);
}
}
diff --git a/frontend/client/modules/crm/src/views/call/list.js b/frontend/client/modules/crm/src/views/call/list.js
index 9d2c039feb..c26346a578 100644
--- a/frontend/client/modules/crm/src/views/call/list.js
+++ b/frontend/client/modules/crm/src/views/call/list.js
@@ -17,56 +17,55 @@
*
* 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.Call.List', 'Views.List', function (Dep) {
return Dep.extend({
-
+
actionSetHeld: function (data) {
var id = data.id;
if (!id) {
return;
- }
+ }
var model = this.collection.get(id);
if (!model) {
return;
}
-
+
model.set('status', 'Held');
-
+
this.listenToOnce(model, 'sync', function () {
this.notify(false);
this.collection.fetch();
}, this);
-
+
this.notify('Saving...');
- model.save();
-
+ model.save();
+
},
-
+
actionSetNotHeld: function (data) {
var id = data.id;
if (!id) {
return;
- }
+ }
var model = this.collection.get(id);
if (!model) {
return;
}
-
+
model.set('status', 'Not Held');
-
+
this.listenToOnce(model, 'sync', function () {
this.notify(false);
this.collection.fetch();
}, this);
-
+
this.notify('Saving...');
- model.save();
-
+ model.save();
},
-
+
});
-
+
});
diff --git a/frontend/client/res/templates/stream/notes/email-received.tpl b/frontend/client/res/templates/stream/notes/email-received.tpl
index 535ee3e902..a89c55f4bf 100644
--- a/frontend/client/res/templates/stream/notes/email-received.tpl
+++ b/frontend/client/res/templates/stream/notes/email-received.tpl
@@ -13,7 +13,7 @@
{{{avatar}}}
-
+
{{{message}}}
diff --git a/frontend/client/src/views/email/record/detail.js b/frontend/client/src/views/email/record/detail.js
index d98f4552c0..f2e5110f29 100644
--- a/frontend/client/src/views/email/record/detail.js
+++ b/frontend/client/src/views/email/record/detail.js
@@ -47,9 +47,6 @@ Espo.define('Views.Email.Record.Detail', 'Views.Record.Detail', function (Dep) {
setup: function () {
Dep.prototype.setup.call(this);
- this.listenTo(this.model, 'change:attachmentsIds', function () {
- this.handleAttachmentField();
- }, this);
},
handleAttachmentField: function () {
@@ -64,8 +61,9 @@ Espo.define('Views.Email.Record.Detail', 'Views.Record.Detail', function (Dep) {
Dep.prototype.afterRender.call(this);
this.handleAttachmentField();
-
-
+ this.listenTo(this.model, 'change:attachmentsIds', function () {
+ this.handleAttachmentField();
+ }, this);
},
});
diff --git a/frontend/client/src/views/record/list.js b/frontend/client/src/views/record/list.js
index a1c2a84e47..f69bfdf96d 100644
--- a/frontend/client/src/views/record/list.js
+++ b/frontend/client/src/views/record/list.js
@@ -132,18 +132,15 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
this.$el.find('.list > table tbody tr').removeClass('active');
}
},
- 'click [data-action="quickEdit"]': function (e) {
- var $target = $(e.currentTarget);
- var id = $target.data('id');
- var data = $target.data();
- this.quickEdit(id, data);
-
- },
- 'click [data-action="quickRemove"]': function (e) {
- var $target = $(e.currentTarget);
- var id = $target.data('id');
- var data = $target.data();
- this.quickRemove(id, data);
+ 'click .action': function (e) {
+ $el = $(e.currentTarget);
+ var action = $el.data('action');
+ var method = 'action' + Espo.Utils.upperCaseFirst(action);
+ if (typeof this[method] == 'function') {
+ var data = $el.data();
+ this[method](data);
+ e.stopPropagation();
+ }
},
'click .checkbox-dropdown [data-action="selectAllResult"]': function (e) {
this.selectAllResult();
@@ -785,8 +782,11 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
});
},
- quickEdit: function (id, d) {
+ actionQuickEdit: function (d) {
d = d || {}
+ var id = d.id;
+ if (!id) return;
+
if (this.allowQuickEdit) {
this.notify('Loading...');
this.createView('quickEdit', 'Modals.Edit', {
@@ -811,7 +811,11 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
return 'tr[data-id="' + id + '"]';
},
- quickRemove: function (id) {
+ actionQuickRemove: function (data) {
+ data = data || {}
+ var id = data.id;
+ if (!id) return;
+
var model = this.collection.get(id);
if (!this.getAcl().checkModel(model, 'delete')) {
this.notify('Access denied', 'error');
diff --git a/frontend/client/src/views/record/panels/bottom.js b/frontend/client/src/views/record/panels/bottom.js
index 1d41fff38a..5d6b37ed9f 100644
--- a/frontend/client/src/views/record/panels/bottom.js
+++ b/frontend/client/src/views/record/panels/bottom.js
@@ -33,7 +33,9 @@ Espo.define('Views.Record.Panels.Bottom', 'View', function (Dep) {
var action = $el.data('action');
var method = 'action' + Espo.Utils.upperCaseFirst(action);
if (typeof this[method] == 'function') {
- this[method]($el.data('id'));
+ var data = $el.data();
+ this[method](data);
+ e.stopPropagation();
}
}
},
@@ -58,6 +60,22 @@ Espo.define('Views.Record.Panels.Bottom', 'View', function (Dep) {
return [];
},
+ actionViewRecord: function (data) {
+ var id = data.id;
+ var scope = data.scope;
+
+ this.notify('Loading...');
+ this.createView('quickDetail', 'Modals.Detail', {
+ scope: scope,
+ id: id
+ }, function (view) {
+ view.once('after:render', function () {
+ Espo.Ui.notify(false);
+ });
+ view.render();
+ }.bind(this));
+ }
+
});
});
diff --git a/frontend/client/src/views/record/panels/default-side.js b/frontend/client/src/views/record/panels/default-side.js
index c795e47f1f..fb97c69f24 100644
--- a/frontend/client/src/views/record/panels/default-side.js
+++ b/frontend/client/src/views/record/panels/default-side.js
@@ -17,7 +17,7 @@
*
* 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.Panels.DefaultSide', 'Views.Record.Panels.Side', function (Dep) {
diff --git a/frontend/client/src/views/record/panels/relationship.js b/frontend/client/src/views/record/panels/relationship.js
index 84bbcc45ce..afcb16e0d5 100644
--- a/frontend/client/src/views/record/panels/relationship.js
+++ b/frontend/client/src/views/record/panels/relationship.js
@@ -138,7 +138,9 @@ Espo.define('Views.Record.Panels.Relationship', ['Views.Record.Panels.Bottom', '
this.collection.fetch();
},
- actionViewRelated: function (id) {
+ actionViewRelated: function (data) {
+ var id = data.id;
+
this.notify('Loading...');
this.createView('quickDetail', 'Modals.Detail', {
scope: this.collection.get(id).name,
@@ -154,7 +156,9 @@ Espo.define('Views.Record.Panels.Relationship', ['Views.Record.Panels.Bottom', '
}.bind(this));
},
- actionEditRelated: function (id) {
+ actionEditRelated: function (data) {
+ var id = data.id;
+
this.notify('Loading...');
this.createView('quickEdit', 'Modals.Edit', {
scope: this.collection.get(id).name,
@@ -170,7 +174,9 @@ Espo.define('Views.Record.Panels.Relationship', ['Views.Record.Panels.Bottom', '
}.bind(this));
},
- actionUnlinkRelated: function (id) {
+ actionUnlinkRelated: function (data) {
+ var id = data.id;
+
var self = this;
if (confirm(this.translate('unlinkRecordConfirmation', 'messages'))) {
var model = this.collection.get(id);
@@ -193,7 +199,9 @@ Espo.define('Views.Record.Panels.Relationship', ['Views.Record.Panels.Bottom', '
}
},
- actionRemoveRelated: function (id) {
+ actionRemoveRelated: function (data) {
+ var id = data.id;
+
var self = this;
if (confirm(this.translate('removeRecordConfirmation', 'messages'))) {
var model = this.collection.get(id);
diff --git a/frontend/client/src/views/stream/list.js b/frontend/client/src/views/stream/list.js
index f1dcf46f96..e8ed50cabe 100644
--- a/frontend/client/src/views/stream/list.js
+++ b/frontend/client/src/views/stream/list.js
@@ -107,6 +107,22 @@ Espo.define('Views.Stream.List', 'Views.Record.ListExpanded', function (Dep) {
});
},
+ actionViewRecord: function (data) {
+ var id = data.id;
+ var scope = data.scope;
+
+ this.notify('Loading...');
+ this.createView('quickDetail', 'Modals.Detail', {
+ scope: scope,
+ id: id
+ }, function (view) {
+ view.once('after:render', function () {
+ Espo.Ui.notify(false);
+ });
+ view.render();
+ }.bind(this));
+ }
+
});
});
diff --git a/frontend/client/src/views/stream/notes/email-received.js b/frontend/client/src/views/stream/notes/email-received.js
index db31e450d3..ce536a326b 100644
--- a/frontend/client/src/views/stream/notes/email-received.js
+++ b/frontend/client/src/views/stream/notes/email-received.js
@@ -27,9 +27,17 @@ Espo.define('Views.Stream.Notes.EmailReceived', 'Views.Stream.Note', function (D
isRemovable: true,
+ data: function () {
+ return _.extend({
+ emailId: this.emailId
+ }, Dep.prototype.data.call(this));
+ },
+
setup: function () {
var data = this.model.get('data') || {};
+ this.emailId = data.emailId;
+
if (this.model.get('post')) {
this.createField('post', null, null, 'Stream.Fields.Post');
}
diff --git a/frontend/client/src/views/stream/notes/email-sent.js b/frontend/client/src/views/stream/notes/email-sent.js
index 3112dd12c6..0ef7f11b44 100644
--- a/frontend/client/src/views/stream/notes/email-sent.js
+++ b/frontend/client/src/views/stream/notes/email-sent.js
@@ -27,9 +27,17 @@ Espo.define('Views.Stream.Notes.EmailSent', 'Views.Stream.Note', function (Dep)
isRemovable: true,
+ data: function () {
+ return _.extend({
+ emailId: this.emailId
+ }, Dep.prototype.data.call(this));
+ },
+
setup: function () {
var data = this.model.get('data') || {};
+ this.emailId = data.emailId;
+
if (this.model.get('post')) {
this.createField('post', null, null, 'Stream.Fields.Post');
}