email improvements

This commit is contained in:
yuri
2015-03-06 17:18:45 +02:00
parent 6657078a89
commit 27ed23cb51
14 changed files with 198 additions and 35 deletions
+20 -7
View File
@@ -18,7 +18,7 @@
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
************************************************************************/
namespace Espo\Controllers;
@@ -29,18 +29,18 @@ use \Espo\Core\Exceptions\Error;
class Email extends \Espo\Core\Controllers\Record
{
public function actionGetCopiedAttachments($params, $data, $request)
{
{
$id = $request->get('id');
return $this->getRecordService()->getCopiedAttachments($id);
}
public function actionSendTestEmail($params, $data, $request)
{
if (!$request->isPost()) {
throw new BadRequest();
}
if (empty($data['password'])) {
if ($data['type'] == 'preferences') {
if (!$this->getUser()->isAdmin() && $data['id'] != $this->getUser()->id) {
@@ -50,7 +50,7 @@ class Email extends \Espo\Core\Controllers\Record
if (!$preferences) {
throw new Error();
}
$data['password'] = $this->getContainer()->get('crypt')->decrypt($preferences->get('smtpPassword'));
} else {
if (!$this->getUser()->isAdmin()) {
@@ -59,8 +59,21 @@ class Email extends \Espo\Core\Controllers\Record
$data['password'] = $this->getConfig()->get('smtpPassword');
}
}
return $this->getRecordService()->sendTestEmail($data);
}
public function actionMarkAsRead($params, $data, $request)
{
if (!$request->isPost()) {
throw new BadRequest();
}
if (empty($data['ids']) || !is_array($data['ids'])) {
throw new BadRequest();
}
$ids = $data['ids'];
return $this->getRecordService()->markAsReadByIds($ids);
}
}
@@ -24,7 +24,8 @@
"Draft": "Draft",
"Sending": "Sending",
"Sent": "Sent",
"Archived": "Archived"
"Archived": "Archived",
"Received": "Received"
},
"labels": {
"Create Email": "Archive Email",
@@ -38,7 +39,8 @@
"Email Accounts": "Email Accounts",
"Send Test Email": "Send Test Email",
"Send": "Send",
"Email Address": "Email Address"
"Email Address": "Email Address",
"Mark Read": "Mark Read"
},
"messages": {
"noSmtpSetup": "No SMTP setup. {link}.",
@@ -1,6 +1,6 @@
[
{"name":"personStringData","width":16,"notSortable": true, "customLabel": ""},
{"name":"name","width":32,"link":true,"notSortable": true},
{"name":"subject","width":32,"link":true,"notSortable": true},
{"name":"status","notSortable": true, "width":10},
{"name":"parent","notSortable": true},
{"name":"dateSent","view": "Fields.DatetimeShort", "notSortable": true, "width":10, "align": "right"}
@@ -8,7 +8,8 @@
"type": "varchar",
"required": true,
"db": false,
"notStorable": true
"notStorable": true,
"view": "Email.Fields.Subject"
},
"fromName": {
"type": "varchar"
@@ -44,6 +45,11 @@
"notStorable": true,
"disabled": true
},
"isRead": {
"type": "bool",
"notStorable": true,
"default": true
},
"nameHash": {
"type": "text",
"notStorable": true,
@@ -101,7 +107,7 @@
},
"status": {
"type": "enum",
"options": ["Draft", "Sending", "Sent", "Archived"],
"options": ["Draft", "Sending", "Sent", "Received", "Archived"],
"readOnly": true,
"default": "Archived"
},
@@ -167,7 +173,13 @@
"users": {
"type": "hasMany",
"entity": "User",
"foreign": "emails"
"foreign": "emails",
"additionalColumns": {
"isRead": {
"type": "bool",
"default": false
}
}
},
"attachments": {
"type": "hasChildren",
+43 -1
View File
@@ -206,10 +206,34 @@ class Email extends Record
$this->loadAttachmentsTypes($entity);
$this->markAsRead($entity->id);
}
return $entity;
}
public function markAsReadByIds(array $ids)
{
foreach ($ids as $id) {
$this->markAsRead($id);
}
return true;
}
public function markAsRead($id)
{
$pdo = $this->getEntityManager()->getPDO();
$sql = "
UPDATE email_user SET is_read = 1
WHERE
deleted = 0 AND
user_id = " . $pdo->quote($this->getUser()->id) . " AND
email_id = " . $pdo->quote($id) . "
";
$pdo->query($sql);
return true;
}
public function loadAdditionalFieldsForList(Entity $entity)
{
parent::loadAdditionalFieldsForList($entity);
@@ -246,8 +270,26 @@ class Email extends Record
}
$entity->set('personStringData', 'To: ' . implode(', ', $arr));
}
}
$pdo = $this->getEntityManager()->getPDO();
$sql = "
SELECT is_read AS 'isRead' FROM email_user
WHERE
deleted = 0 AND
user_id = " . $pdo->quote($this->getUser()->id) . " AND
email_id = " . $pdo->quote($entity->id) . "
";
$sth = $pdo->prepare($sql);
$sth->execute();
if ($row = $sth->fetch(\PDO::FETCH_ASSOC)) {
$isRead = !empty($row['isRead']) ? true : false;
} else {
$isRead = true;
}
$entity->set('isRead', $isRead);
}
protected function loadAttachmentsTypes(Entity $entity)
@@ -0,0 +1,3 @@
{{#unless isRead}}<strong>{{/unless}}
<a href="#{{model.name}}/view/{{model.id}}" class="link" data-id="{{model.id}}" title="{{value}}">{{value}}</a>
{{#unless isRead}}</strong>{{/unless}}
@@ -6,7 +6,7 @@
{{{pagination}}}
</div>
{{/if}}
{{#if checkboxes}}
<div class="btn-group actions">
<button type="button" class="btn btn-default btn-sm dropdown-toggle actions-button" data-toggle="dropdown" disabled>
@@ -14,12 +14,12 @@
</button>
<ul class="dropdown-menu">
{{#each actions}}
<li><a href="javascript:" data-action="{{name}}">{{translate label scope=../scope}}</a></li>
<li><a href="javascript:" data-action="{{name}}" class='mass-action'>{{translate label scope=../scope}}</a></li>
{{/each}}
</ul>
</div>
{{/if}}
</div>
</div>
{{/if}}
<div class="list list-expanded">
@@ -35,7 +35,7 @@
{{#if showCount}}
<div class="pull-right text-muted more-count">{{moreCount}}</div>
{{/if}}
<span>{{translate 'Show more'}}</span>
<span>{{translate 'Show more'}}</span>
</a>
</div>
{{/if}}
@@ -17,7 +17,7 @@
</button>
<ul class="dropdown-menu">
{{#each actions}}
<li><a href="javascript:" data-action="{{name}}">{{translate label scope=../scope}}</a></li>
<li><a href="javascript:" data-action="{{name}}" class='mass-action'>{{translate label scope=../scope}}</a></li>
{{/each}}
</ul>
</div>
+11 -2
View File
@@ -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/.
************************************************************************/
************************************************************************/
(function (Espo, Backbone, _, Bull, $) {
Espo.View = Bull.View.extend({
@@ -43,6 +43,15 @@
Espo.Ui.notify(text, type, timeout);
},
reRender: function () {
if (this.isRendered()) {
this.render();
} else if (this.isBeingRendered()) {
this.once('after:render', function () {
this.render();
}, this);
}
},
getHelper: function () {
return this._helper;
@@ -131,7 +140,7 @@
return this._helper.fieldManager;
}
},
getBaseController: function () {
if (this._helper) {
return this._helper.baseController;
@@ -0,0 +1,50 @@
/************************************************************************
* 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.Email.Fields.Subject', 'Views.Fields.Varchar', function (Dep) {
return Dep.extend({
listLinkTemplate: 'email.fields.subject.list-link',
data: function () {
return _.extend({
'isRead': this.model.get('isRead')
}, Dep.prototype.data.call(this));
},
getValueForDisplay: function () {
return this.model.get('name');
},
getAttributeList: function () {
return ['name', 'isRead'];
},
setup: function () {
Dep.prototype.setup.call(this);
this.listenTo(this.model, 'change:isRead', function () {
this.reRender();
}, this);
}
});
});
+1
View File
@@ -59,6 +59,7 @@ Espo.define('Views.Email.List', 'Views.List', function (Dep) {
};
},
});
});
+33 -5
View File
@@ -17,18 +17,46 @@
*
* 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.Email.Record.List', 'Views.Record.List', function (Dep) {
return Dep.extend({
mergeAction: false,
massUpdateAction: false,
exportAction: false,
setup: function () {
Dep.prototype.setup.call(this);
this.actions.push({
name: 'markAsRead',
label: 'Mark Read',
action: function (e) {
var ids = [];
for (var i in this.checkedList) {
ids.push(this.checkedList[i]);
}
$.ajax({
url: 'Email/action/markAsRead',
type: 'POST',
data: JSON.stringify({
ids: ids
})
});
ids.forEach(function (id) {
var model = this.collection.get(id);
if (model) {
model.set('isRead', true);
}
}, this);
}.bind(this)
});
},
});
});
+1 -7
View File
@@ -280,13 +280,7 @@ Espo.define('Views.Fields.Base', 'View', function (Dep) {
});
if (changed) {
if (this.isRendered()) {
this.render();
} else if (this.isBeingRendered()) {
this.once('after:render', function () {
this.render();
}, this);
}
this.reRender();
}
}
}.bind(this));
+11 -2
View File
@@ -145,6 +145,15 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
'click .checkbox-dropdown [data-action="selectAllResult"]': function (e) {
this.selectAllResult();
},
'click .actions a.mass-action': function (e) {
$el = $(e.currentTarget);
var action = $el.data('action');
this.actions.forEach(function (item) {
if (item.name == action) {
item.action.call(this, e);
}
}, this);
}
},
actions: [],
@@ -430,13 +439,13 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
this.actions = [];
}
if (this.checkboxes) {
/*if (this.checkboxes) {
this.actions.forEach(function (item) {
this.events['click .actions a[data-action="' + item.name + '"]'] = function (e) {
item.action.call(this, e);
}.bind(this);
}.bind(this));
}
}*/
this.listenTo(this.collection, 'sync', function () {
if (this.noRebuild) {