mirror of
https://github.com/espocrm/espocrm.git
synced 2026-03-04 01:57:01 +00:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f45e26028 | ||
|
|
f6892877c1 | ||
|
|
c7cc44edf6 | ||
|
|
e958d7c488 | ||
|
|
77ff11990b | ||
|
|
994e0c1eda | ||
|
|
d51e88be60 | ||
|
|
9595d528a8 | ||
|
|
9bfb27e10a | ||
|
|
be50630d2f | ||
|
|
d8b629a5a0 | ||
|
|
6d0b39f2b6 | ||
|
|
b778f74628 | ||
|
|
6db658c0b3 | ||
|
|
6fb88665bb | ||
|
|
f20a47542a | ||
|
|
c77e3b7e92 | ||
|
|
e7b033304c | ||
|
|
2b8a8d23eb | ||
|
|
0f59f79a9e | ||
|
|
2904cd1f53 | ||
|
|
d87ae60fea | ||
|
|
0d17cf6e78 | ||
|
|
81739d59f5 | ||
|
|
7704d5afd0 | ||
|
|
da268f2b29 | ||
|
|
01dc251ef2 | ||
|
|
9054d70f4c | ||
|
|
788b265cd4 | ||
|
|
c96640bcb1 |
@@ -155,6 +155,7 @@ module.exports = function (grunt) {
|
||||
'bootstrap.php',
|
||||
'cron.php',
|
||||
'rebuild.php',
|
||||
'clear_cache.php',
|
||||
'upgrade.php',
|
||||
'index.php',
|
||||
'LICENSE.txt',
|
||||
|
||||
@@ -41,7 +41,7 @@ class Email extends \Espo\Core\Controllers\Record
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
if (empty($data['password'])) {
|
||||
if (is_null($data['password'])) {
|
||||
if ($data['type'] == 'preferences') {
|
||||
if (!$this->getUser()->isAdmin() && $data['id'] != $this->getUser()->id) {
|
||||
throw new Forbidden();
|
||||
|
||||
@@ -44,5 +44,27 @@ class EmailAccount extends \Espo\Core\Controllers\Record
|
||||
throw new Forbidden();
|
||||
}
|
||||
}
|
||||
|
||||
public function actionTestConnection($params, $data, $request)
|
||||
{
|
||||
if (!$request->isPost()) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
if (is_null($data['password'])) {
|
||||
$emailAccount = $this->getEntityManager()->getEntity('EmailAccount', $data['id']);
|
||||
if (!$emailAccount) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
if ($emailAccount->get('assignedUserId') != $this->getUser()->id && !$this->getUser()->isAdmin()) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
||||
$data['password'] = $this->getContainer()->get('crypt')->decrypt($emailAccount->get('password'));
|
||||
}
|
||||
|
||||
return $this->getRecordService()->testConnection($data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -138,6 +138,12 @@ class Application
|
||||
$dataManager->rebuild();
|
||||
}
|
||||
|
||||
public function runClearCache()
|
||||
{
|
||||
$dataManager = $this->getContainer()->get('dataManager');
|
||||
$dataManager->clearCache();
|
||||
}
|
||||
|
||||
public function isInstalled()
|
||||
{
|
||||
$config = $this->getContainer()->get('config');
|
||||
|
||||
@@ -110,7 +110,9 @@ class Importer
|
||||
$dateSent = $dt->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i:s');
|
||||
$email->set('dateSent', $dateSent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$email->set('dateSent', date('Y-m-d H:i:s'));
|
||||
}
|
||||
if (isset($message->deliveryDate)) {
|
||||
$dt = new \DateTime($message->deliveryDate);
|
||||
if ($dt) {
|
||||
|
||||
@@ -307,7 +307,7 @@ class Sender
|
||||
|
||||
$this->transport->send($message);
|
||||
|
||||
$email->set('messageId', $messageId);
|
||||
$email->set('messageId', '<' . $messageId . '>');
|
||||
$email->set('status', 'Sent');
|
||||
$email->set('dateSent', date("Y-m-d H:i:s"));
|
||||
} catch (\Exception $e) {
|
||||
|
||||
@@ -27,13 +27,6 @@ use Espo\Core\Utils\Util;
|
||||
|
||||
class Install extends \Espo\Core\Upgrades\Actions\Base
|
||||
{
|
||||
/**
|
||||
* Is copied extension files to Espo
|
||||
*
|
||||
* @var [type]
|
||||
*/
|
||||
protected $isCopied = null;
|
||||
|
||||
/**
|
||||
* Main installation process
|
||||
*
|
||||
@@ -54,8 +47,6 @@ class Install extends \Espo\Core\Upgrades\Actions\Base
|
||||
|
||||
$this->initialize();
|
||||
|
||||
$this->isCopied = false;
|
||||
|
||||
/** check if an archive is unzipped, if no then unzip */
|
||||
$packagePath = $this->getPackagePath();
|
||||
if (!file_exists($packagePath)) {
|
||||
@@ -77,7 +68,6 @@ class Install extends \Espo\Core\Upgrades\Actions\Base
|
||||
if (!$this->copyFiles()) {
|
||||
$this->throwErrorAndRemovePackage('Cannot copy files.');
|
||||
}
|
||||
$this->isCopied = true;
|
||||
|
||||
/* remove files defined in a manifest */
|
||||
$this->deleteFiles(true);
|
||||
@@ -103,10 +93,6 @@ class Install extends \Espo\Core\Upgrades\Actions\Base
|
||||
|
||||
protected function restoreFiles()
|
||||
{
|
||||
if (!$this->isCopied) {
|
||||
return;
|
||||
}
|
||||
|
||||
$GLOBALS['log']->info('Installer: Restore previous files.');
|
||||
|
||||
$backupPath = $this->getPath('backupPath');
|
||||
|
||||
@@ -160,7 +160,7 @@ class Install extends \Espo\Core\Upgrades\Actions\Base\Install
|
||||
$extensionEntity = $this->getExtensionEntity();
|
||||
|
||||
if (isset($extensionEntity)) {
|
||||
$comparedVersion = version_compare($manifest['version'], $extensionEntity->get('version'));
|
||||
$comparedVersion = version_compare($manifest['version'], $extensionEntity->get('version'), '>=');
|
||||
if ($comparedVersion <= 0) {
|
||||
$this->throwErrorAndRemovePackage('You cannot install an older version of this extension.');
|
||||
}
|
||||
|
||||
@@ -472,7 +472,7 @@ class Manager
|
||||
$sourceFile = is_file($sourcePath) ? $sourcePath : $this->concatPaths(array($sourcePath, $file));
|
||||
$destFile = $this->concatPaths(array($destPath, $file));
|
||||
|
||||
if (file_exists($sourceFile)) {
|
||||
if (file_exists($sourceFile) && is_file($sourceFile)) {
|
||||
$res &= copy($sourceFile, $destFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ class Layout
|
||||
}
|
||||
|
||||
$layoutPath = $this->getLayoutPath($controllerName, true);
|
||||
$data = Json::encode($layoutData);
|
||||
$data = Json::encode($layoutData, \JSON_PRETTY_PRINT);
|
||||
|
||||
$result &= $this->getFileManager()->putContents(array($layoutPath, $layoutName.'.json'), $data);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ class Notifications extends \Espo\Core\Hooks\Base
|
||||
|
||||
$className = '\\Espo\\Custom\\Notificators\\' . $normalizedName;
|
||||
if (!class_exists($className)) {
|
||||
$moduleName = $this->getMetadata()->getScopeModuleName($entityName);
|
||||
$moduleName = $this->getMetadata()->getScopeModuleName($entityType);
|
||||
if ($moduleName) {
|
||||
$className = '\\Espo\\Modules\\' . $moduleName . '\\Notificators\\' . $normalizedName;
|
||||
} else {
|
||||
|
||||
@@ -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\Modules\Crm\Controllers;
|
||||
|
||||
@@ -30,9 +30,9 @@ class InboundEmail extends \Espo\Core\Controllers\Record
|
||||
throw new Forbidden();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function actionGetFolders($params, $data, $request)
|
||||
{
|
||||
{
|
||||
return $this->getRecordService()->getFolders(array(
|
||||
'host' => $request->get('host'),
|
||||
'port' => $request->get('port'),
|
||||
@@ -41,7 +41,23 @@ class InboundEmail extends \Espo\Core\Controllers\Record
|
||||
'password' => $request->get('password'),
|
||||
'id' => $request->get('id')
|
||||
));
|
||||
}
|
||||
|
||||
public function actionTestConnection($params, $data, $request)
|
||||
{
|
||||
if (!$request->isPost()) {
|
||||
throw new BadRequest();
|
||||
}
|
||||
|
||||
if (is_null($data['password'])) {
|
||||
$inboundEmail = $this->getEntityManager()->getEntity('InboundEmail', $data['id']);
|
||||
if (!$inboundEmail) {
|
||||
throw new Error();
|
||||
}
|
||||
$data['password'] = $this->getContainer()->get('crypt')->decrypt($inboundEmail->get('password'));
|
||||
}
|
||||
|
||||
return $this->getRecordService()->testConnection($data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1 +1,14 @@
|
||||
[{"label":"","rows":[[{"name":"name"}],[{"name":"status"}],[{"name":"direction"}],[{"name":"dateStart"}],[{"name":"duration"}],[{"name":"parent"}]]}]
|
||||
[
|
||||
{
|
||||
"label":"",
|
||||
"rows":[
|
||||
[{"name":"name"}],
|
||||
[{"name":"status"}],
|
||||
[{"name":"direction"}],
|
||||
[{"name":"dateStart"}],
|
||||
[{"name":"duration"}],
|
||||
[{"name":"parent"}],
|
||||
[{"name":"description"}]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1 +1,13 @@
|
||||
[{"label":"","rows":[[{"name":"name"}],[{"name":"status"}],[{"name":"priority"}],[{"name":"type"}],[{"name":"account"}]]}]
|
||||
[
|
||||
{
|
||||
"label":"",
|
||||
"rows":[
|
||||
[{"name":"name"}],
|
||||
[{"name":"status"}],
|
||||
[{"name":"priority"}],
|
||||
[{"name":"type"}],
|
||||
[{"name":"account"}],
|
||||
[{"name":"description"}]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -26,7 +26,8 @@
|
||||
],
|
||||
[
|
||||
{"name":"monitoredFolders"},{"name":"password"}
|
||||
]
|
||||
],
|
||||
[{"name": "testConnection", "customLabel": null, "view": "Crm:InboundEmail.Fields.TestConnection"}]
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1 +1,14 @@
|
||||
[{"label":"","rows":[[{"name":"name"}],[{"name":"status"}],[{"name":"dateStart"}],[{"name":"duration"}],[{"name":"dateEnd"}],[{"name":"parent"}]]}]
|
||||
[
|
||||
{
|
||||
"label":"",
|
||||
"rows":[
|
||||
[{"name":"name"}],
|
||||
[{"name":"status"}],
|
||||
[{"name":"dateStart"}],
|
||||
[{"name":"duration"}],
|
||||
[{"name":"dateEnd"}],
|
||||
[{"name":"parent"}],
|
||||
[{"name":"description"}]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1 +1,14 @@
|
||||
[{"label":"","rows":[[{"name":"name"}],[{"name":"status"}],[{"name":"priority"}],[{"name":"dateStart"}],[{"name":"dateEnd"}],[{"name":"parent"}]]}]
|
||||
[
|
||||
{
|
||||
"label":"",
|
||||
"rows":[
|
||||
[{"name":"name"}],
|
||||
[{"name":"status"}],
|
||||
[{"name":"priority"}],
|
||||
[{"name":"dateStart"}],
|
||||
[{"name":"dateEnd"}],
|
||||
[{"name":"parent"}],
|
||||
[{"name":"description"}]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -266,6 +266,28 @@ class Activities extends \Espo\Core\Services\Base
|
||||
entity_email_address_2.entity_type = " . $this->getPDO()->quote($scope) . " AND
|
||||
entity_email_address_2.deleted = 0
|
||||
|
||||
";
|
||||
$sql .= "
|
||||
WHERE
|
||||
email.deleted = 0 AND
|
||||
(
|
||||
email.parent_type <> ".$this->getPDO()->quote($scope)." OR
|
||||
email.parent_id <> ".$this->getPDO()->quote($id)." OR
|
||||
email.parent_type IS NULL OR
|
||||
email.parent_id IS NULL
|
||||
) AND
|
||||
(entity_email_address_2.entity_id = ".$this->getPDO()->quote($id).")
|
||||
";
|
||||
if (!empty($notIn)) {
|
||||
$sql .= "
|
||||
AND email.status {$op} ('". implode("', '", $notIn) . "')
|
||||
";
|
||||
}
|
||||
|
||||
$sql = $sql . "
|
||||
UNION
|
||||
" . $baseSql;
|
||||
$sql .= "
|
||||
LEFT JOIN email_email_address ON
|
||||
email_email_address.email_id = email.id AND
|
||||
email_email_address.deleted = 0
|
||||
@@ -284,7 +306,7 @@ class Activities extends \Espo\Core\Services\Base
|
||||
email.parent_type IS NULL OR
|
||||
email.parent_id IS NULL
|
||||
) AND
|
||||
(entity_email_address_1.entity_id = ".$this->getPDO()->quote($id)." OR entity_email_address_2.entity_id = ".$this->getPDO()->quote($id).")
|
||||
(entity_email_address_1.entity_id = ".$this->getPDO()->quote($id).")
|
||||
";
|
||||
if (!empty($notIn)) {
|
||||
$sql .= "
|
||||
|
||||
@@ -121,6 +121,27 @@ class InboundEmail extends \Espo\Services\Record
|
||||
return $foldersArr;
|
||||
}
|
||||
|
||||
public function testConnection(array $params)
|
||||
{
|
||||
$imapParams = array(
|
||||
'host' => $params['host'],
|
||||
'port' => $params['port'],
|
||||
'user' => $params['username'],
|
||||
'password' => $params['password']
|
||||
);
|
||||
|
||||
if (!empty($params['ssl'])) {
|
||||
$imapParams['ssl'] = 'SSL';
|
||||
}
|
||||
|
||||
$storage = new \Espo\Core\Mail\Mail\Storage\Imap($imapParams);
|
||||
|
||||
if ($storage->getFolders()) {
|
||||
return true;
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
public function fetchFromMailServer(Entity $inboundEmail)
|
||||
{
|
||||
if ($inboundEmail->get('status') != 'Active') {
|
||||
@@ -230,7 +251,7 @@ class InboundEmail extends \Espo\Services\Record
|
||||
}
|
||||
|
||||
if ($k == count($ids) - 1) {
|
||||
if ($message) {
|
||||
if ($message && isset($message->date)) {
|
||||
$dt = new \DateTime($message->date);
|
||||
if ($dt) {
|
||||
$dateSent = $dt->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i:s');
|
||||
@@ -385,7 +406,7 @@ class InboundEmail extends \Espo\Services\Record
|
||||
}
|
||||
|
||||
$contact = $this->getEntityManager()->getRepository('Contact')->where(array(
|
||||
'EmailAddress.id' => $email->get('fromEmailAddressId')
|
||||
'emailAddresses.id' => $email->get('fromEmailAddressId')
|
||||
))->findOne();
|
||||
if ($contact) {
|
||||
$case->set('contactId', $contact->id);
|
||||
|
||||
@@ -60,7 +60,7 @@ class Email extends \Espo\Core\Notificators\Base
|
||||
|
||||
$userIdList = [];
|
||||
foreach ($emailUserIdList as $userId) {
|
||||
if (!in_array($userId, $userIdList) && !in_array() && $userId != $this->getUser()->id) {
|
||||
if (!in_array($userId, $userIdList) && $userId != $this->getUser()->id) {
|
||||
$userIdList[] = $userId;
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,13 @@ class Email extends \Espo\Core\Notificators\Base
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($data['personEntityId'])) {
|
||||
$data['fromString'] = \Espo\Services\Email::parseFromName($entity->get('fromString'));
|
||||
if (empty($data['fromString']) && $from) {
|
||||
$data['fromString'] = $from;
|
||||
}
|
||||
}
|
||||
|
||||
$parent = null;
|
||||
if ($entity->get('parentId') && $entity->get('parentType')) {
|
||||
$parent = $this->getEntityManager()->getEntity($entity->get('parentType'), $entity->get('parentId'));
|
||||
|
||||
@@ -128,7 +128,7 @@ abstract class Base
|
||||
$params['leftJoins'] = array();
|
||||
}
|
||||
|
||||
$joinsPart = $this->getBelongsToJoins($entity, $params['select'], $params['joins'] + $params['leftJoins']);
|
||||
$joinsPart = $this->getBelongsToJoins($entity, $params['select'], array_merge($params['joins'], $params['leftJoins']));
|
||||
|
||||
$wherePart = $this->getWhere($entity, $whereClause);
|
||||
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
"labels": {
|
||||
"Create EmailAccount": "Create Email Account",
|
||||
"IMAP": "IMAP",
|
||||
"Main": "Main"
|
||||
"Main": "Main",
|
||||
"Test Connection": "Test Connection"
|
||||
},
|
||||
"messages": {
|
||||
"couldNotConnectToImap": "Could not connect to IMAP server"
|
||||
"couldNotConnectToImap": "Could not connect to IMAP server",
|
||||
"connectionIsOk": "Connection is Ok"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
],
|
||||
[
|
||||
{"name":"monitoredFolders"},{"name":"password"}
|
||||
]
|
||||
],
|
||||
[{"name": "testConnection", "customLabel": null, "view": "EmailAccount.Fields.TestConnection"}]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -105,12 +105,12 @@ class Email extends \Espo\Core\SelectManagers\Base
|
||||
if (empty($result['customJoin'])) {
|
||||
$result['customJoin'] = '';
|
||||
}
|
||||
if (stripos($result['customJoin'], 'email_email_address') === false) {
|
||||
if (stripos($result['customJoin'], 'emailEmailAddress') === false) {
|
||||
$result['customJoin'] .= "
|
||||
LEFT JOIN email_email_address
|
||||
LEFT JOIN email_email_address AS `emailEmailAddress`
|
||||
ON
|
||||
email_email_address.email_id = email.id AND
|
||||
email_email_address.deleted = 0
|
||||
emailEmailAddress.email_id = email.id AND
|
||||
emailEmailAddress.deleted = 0
|
||||
";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,12 +104,15 @@ class Email extends Record
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->getStreamService()->noteEmailSent($parent, $entity);
|
||||
}
|
||||
}
|
||||
|
||||
$emailSender->send($entity, $params);
|
||||
|
||||
if ($parent) {
|
||||
$this->getStreamService()->noteEmailSent($parent, $entity);
|
||||
}
|
||||
|
||||
$this->getEntityManager()->saveEntity($entity);
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,27 @@ class EmailAccount extends Record
|
||||
return $foldersArr;
|
||||
}
|
||||
|
||||
public function testConnection(array $params)
|
||||
{
|
||||
$imapParams = array(
|
||||
'host' => $params['host'],
|
||||
'port' => $params['port'],
|
||||
'user' => $params['username'],
|
||||
'password' => $params['password']
|
||||
);
|
||||
|
||||
if (!empty($params['ssl'])) {
|
||||
$imapParams['ssl'] = 'SSL';
|
||||
}
|
||||
|
||||
$storage = new \Espo\Core\Mail\Mail\Storage\Imap($imapParams);
|
||||
|
||||
if ($storage->getFolders()) {
|
||||
return true;
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
public function createEntity($data)
|
||||
{
|
||||
if (!$this->getUser()->isAdmin()) {
|
||||
@@ -224,7 +245,7 @@ class EmailAccount extends Record
|
||||
if ($k == count($ids) - 1) {
|
||||
$lastUID = $storage->getUniqueId($id);
|
||||
|
||||
if ($message) {
|
||||
if ($message && isset($message->date)) {
|
||||
$dt = new \DateTime($message->date);
|
||||
if ($dt) {
|
||||
$dateSent = $dt->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i:s');
|
||||
|
||||
@@ -257,35 +257,83 @@ class Stream extends \Espo\Core\Services\Base
|
||||
$offset = intval($params['offset']);
|
||||
$maxSize = intval($params['maxSize']);
|
||||
|
||||
$selectParams = array(
|
||||
'offset' => $offset,
|
||||
'limit' => $maxSize + 1,
|
||||
'orderBy' => 'number',
|
||||
'order' => 'DESC',
|
||||
'distinct' => true,
|
||||
'customJoin' => "
|
||||
JOIN subscription ON
|
||||
$pdo = $this->getEntityManager()->getPDO();
|
||||
|
||||
|
||||
$sql = "
|
||||
(
|
||||
SELECT
|
||||
note.id AS 'id',
|
||||
note.number AS 'number',
|
||||
note.type AS 'type',
|
||||
note.post AS 'post',
|
||||
note.data AS 'data',
|
||||
note.parent_type AS 'parentType',
|
||||
note.parent_id AS 'parentId',
|
||||
note.created_at AS 'createdAt',
|
||||
note.created_by_id AS 'createdById',
|
||||
TRIM(CONCAT(createdBy.first_name, ' ', createdBy.last_name)) AS `createdByName`
|
||||
FROM `note` AS `note`
|
||||
JOIN subscription AS `subscription` ON
|
||||
(
|
||||
(
|
||||
note.parent_type = subscription.entity_type AND
|
||||
note.parent_id = subscription.entity_id
|
||||
)
|
||||
) AND
|
||||
subscription.user_id = ".$pdo->quote($this->getUser()->id)."
|
||||
LEFT JOIN `user` AS `createdBy` ON note.created_by_id = createdBy.id
|
||||
WHERE note.deleted = 0 {where}
|
||||
ORDER BY number DESC
|
||||
)
|
||||
UNION
|
||||
(
|
||||
SELECT
|
||||
note.id AS 'id',
|
||||
note.number AS 'number',
|
||||
note.type AS 'type',
|
||||
note.post AS 'post',
|
||||
note.data AS 'data',
|
||||
note.parent_type AS 'parentType',
|
||||
note.parent_id AS 'parentId',
|
||||
note.created_at AS 'createdAt',
|
||||
note.created_by_id AS 'createdById',
|
||||
TRIM(CONCAT(createdBy.first_name, ' ', createdBy.last_name)) AS `createdByName`
|
||||
FROM `note` AS `note`
|
||||
JOIN subscription AS `subscription` ON
|
||||
(
|
||||
(
|
||||
note.super_parent_type = subscription.entity_type AND
|
||||
note.super_parent_id = subscription.entity_id
|
||||
)
|
||||
) AND
|
||||
subscription.user_id = ".$pdo->quote($this->getUser()->id)."
|
||||
LEFT JOIN `user` AS `createdBy` ON note.created_by_id = createdBy.id
|
||||
WHERE note.deleted = 0 AND
|
||||
(
|
||||
(
|
||||
note.parent_type = subscription.entity_type AND
|
||||
note.parent_id = subscription.entity_id
|
||||
) OR
|
||||
(
|
||||
note.super_parent_type = subscription.entity_type AND
|
||||
note.super_parent_id = subscription.entity_id
|
||||
)
|
||||
) AND
|
||||
subscription.user_id = '" . $this->getUser()->id . "'
|
||||
"
|
||||
);
|
||||
note.parent_id <> note.super_parent_id
|
||||
OR
|
||||
note.parent_type <> note.super_parent_type
|
||||
)
|
||||
{where}
|
||||
ORDER BY number DESC
|
||||
)
|
||||
ORDER BY number DESC
|
||||
";
|
||||
|
||||
if (!empty($params['after'])) {
|
||||
$where = array();
|
||||
$where['createdAt>'] = $params['after'];
|
||||
$selectParams['whereClause'] = $where;
|
||||
$sql = str_replace('{where}', "AND note.created_at > ".$pdo->quote($params['after']), $sql);
|
||||
} else {
|
||||
$sql = str_replace('{where}', '', $sql);
|
||||
}
|
||||
|
||||
$collection = $this->getEntityManager()->getRepository('Note')->find($selectParams);
|
||||
$sql = $this->getEntityManager()->getQuery()->limit($sql, $offset, $maxSize + 1);
|
||||
|
||||
|
||||
$collection = $this->getEntityManager()->getRepository('Note')->findByQuery($sql);
|
||||
|
||||
foreach ($collection as $e) {
|
||||
if ($e->get('type') == 'Post' || $e->get('type') == 'EmailReceived') {
|
||||
|
||||
33
clear_cache.php
Normal file
33
clear_cache.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* 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/.
|
||||
************************************************************************/
|
||||
|
||||
$sapiName = php_sapi_name();
|
||||
|
||||
if (substr($sapiName, 0, 3) != 'cli') {
|
||||
die("Rebuild can be run only via CLI");
|
||||
}
|
||||
|
||||
include "bootstrap.php";
|
||||
|
||||
$app = new \Espo\Core\Application();
|
||||
$app->runClearCache();
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/************************************************************************
|
||||
* 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('Crm:Views.InboundEmail.Fields.TestConnection', 'Views.EmailAccount.Fields.TestConnection', function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
url: 'InboundEmail/action/testConnection',
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -23,7 +23,9 @@ Espo.define('Crm:Views.InboundEmail.Record.List', 'Views.Record.List', function
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
allowQuickEdit: false,
|
||||
quickDetailDisabled: true,
|
||||
|
||||
quickEditDisabled: true,
|
||||
|
||||
massActionList: ['remove'],
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<div class="input-group add-team">
|
||||
<input class="main-element form-control" type="text" name="" value="" autocomplete="off" placeholder="{{translate 'Select'}}">
|
||||
<span class="input-group-btn">
|
||||
<button data-action="selectLink" class="btn btn-default" type="button" tabindex="-1"><span class="glyphicon glyphicon-arrow-up"></span></button>
|
||||
<span class="input-group-btn">
|
||||
<button data-action="selectLink" class="btn btn-default" type="button" tabindex="-1" title="{{translate 'Select'}}"><span class="glyphicon glyphicon-arrow-up"></span></button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
<div class="input-group add-team">
|
||||
<input class="main-element form-control" type="text" name="" value="" autocomplete="off" placeholder="{{translate 'Select'}}">
|
||||
<span class="input-group-btn">
|
||||
<button data-action="selectLink" class="btn btn-default" type="button" tabindex="-1"><span class="glyphicon glyphicon-arrow-up"></span></button>
|
||||
<span class="input-group-btn">
|
||||
<button data-action="selectLink" class="btn btn-default" type="button" tabindex="-1" title="{{translate 'Select'}}"><span class="glyphicon glyphicon-arrow-up"></span></button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
{{options foreignScopeList foreignScope category='scopeNames'}}
|
||||
</select>
|
||||
</span>
|
||||
<input class="main-element form-control" type="text" name="{{nameName}}" value="{{nameValue}}" autocomplete="off">
|
||||
<span class="input-group-btn">
|
||||
<button data-action="selectLink" class="btn btn-default" type="button" tabindex="-1"><i class="glyphicon glyphicon-arrow-up"></i></button>
|
||||
<input class="main-element form-control" type="text" name="{{nameName}}" value="{{nameValue}}" autocomplete="off" placeholder="{{translate 'Select'}}">
|
||||
<span class="input-group-btn">
|
||||
<button data-action="selectLink" class="btn btn-default" type="button" tabindex="-1" title="{{translate 'Select'}}"><i class="glyphicon glyphicon-arrow-up"></i></button>
|
||||
<button data-action="clearLink" class="btn btn-default" type="button" tabindex="-1"><i class="glyphicon glyphicon-remove"></i></button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
{{options foreignScopeList searchParams.valueType category='scopeNames'}}
|
||||
</select>
|
||||
<div class="input-group">
|
||||
<input class="form-control input-sm" type="text" name="{{nameName}}" value="{{searchParams.valueName}}" autocomplete="off">
|
||||
<span class="input-group-btn">
|
||||
<button type="button" class="btn btn-sm btn-default" data-action="selectLink" tabindex="-1"><i class="glyphicon glyphicon-arrow-up"></i></button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-action="clearLink" tabindex="-1"><i class="glyphicon glyphicon-remove"></i></button>
|
||||
<input class="form-control input-sm" type="text" name="{{nameName}}" value="{{searchParams.valueName}}" autocomplete="off" placeholder="{{translate 'Select'}}">
|
||||
<span class="input-group-btn">
|
||||
<button type="button" class="btn btn-sm btn-default" data-action="selectLink" tabindex="-1" title="{{translate 'Select'}}"><i class="glyphicon glyphicon-arrow-up"></i></button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-action="clearLink" tabindex="-1"><i class="glyphicon glyphicon-remove"></i></button>
|
||||
</span>
|
||||
</div>
|
||||
<input type="hidden" name="{{idName}}" value="{{searchParams.valueId}}">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="input-group">
|
||||
<input class="main-element form-control" type="text" name="{{nameName}}" value="{{nameValue}}" autocomplete="off">
|
||||
<span class="input-group-btn">
|
||||
<button data-action="selectLink" class="btn btn-default" type="button" tabindex="-1"><i class="glyphicon glyphicon-arrow-up"></i></button>
|
||||
<input class="main-element form-control" type="text" name="{{nameName}}" value="{{nameValue}}" autocomplete="off" placeholder="{{translate 'Select'}}">
|
||||
<span class="input-group-btn">
|
||||
<button data-action="selectLink" class="btn btn-default" type="button" tabindex="-1" title="{{translate 'Select'}}"><i class="glyphicon glyphicon-arrow-up"></i></button>
|
||||
<button data-action="clearLink" class="btn btn-default" type="button" tabindex="-1"><i class="glyphicon glyphicon-remove"></i></button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<div class="input-group">
|
||||
<input class="form-control input-sm" type="text" name="{{nameName}}" value="{{searchParams.valueName}}" autocomplete="off">
|
||||
<span class="input-group-btn">
|
||||
<button type="button" class="btn btn-sm btn-default" data-action="selectLink" tabindex="-1"><i class="glyphicon glyphicon-arrow-up"></i></button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-action="clearLink" tabindex="-1"><i class="glyphicon glyphicon-remove"></i></button>
|
||||
<input class="form-control input-sm" type="text" name="{{nameName}}" value="{{searchParams.valueName}}" autocomplete="off" placeholder="{{translate 'Select'}}">
|
||||
<span class="input-group-btn">
|
||||
<button type="button" class="btn btn-sm btn-default" data-action="selectLink" tabindex="-1" title="{{translate 'Select'}}"><i class="glyphicon glyphicon-arrow-up"></i></button>
|
||||
<button type="button" class="btn btn-sm btn-default" data-action="clearLink" tabindex="-1"><i class="glyphicon glyphicon-remove"></i></button>
|
||||
</span>
|
||||
</div>
|
||||
<input type="hidden" name="{{idName}}" value="{{searchParams.value}}">
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
<link href="client/css/font-awesome.min.css" rel="stylesheet">
|
||||
<link href="client/css/summernote.css" rel="stylesheet">
|
||||
|
||||
<textarea class="main-element form-control summernote" name="{{name}}" {{#if params.maxLength}} maxlength="{{params.maxLength}}"{{/if}} {{#if params.rows}} rows="{{params.rows}}"{{/if}}>{{value}}</textarea>
|
||||
<textarea class="main-element form-control summernote" name="{{name}}" {{#if params.maxLength}} maxlength="{{params.maxLength}}"{{/if}} {{#if params.rows}} rows="{{params.rows}}"{{/if}}></textarea>
|
||||
|
||||
@@ -414,7 +414,7 @@ _.extend(Espo.App.prototype, {
|
||||
this.language.load(function () {
|
||||
langIsLoaded = true;
|
||||
handleProcess();
|
||||
}.bind(this));
|
||||
}.bind(this), true);
|
||||
|
||||
|
||||
if (!userIsLoaded) {
|
||||
|
||||
@@ -29,9 +29,9 @@ _.extend(Espo.Language.prototype, {
|
||||
data: null,
|
||||
|
||||
cache: null,
|
||||
|
||||
|
||||
url: 'I18n',
|
||||
|
||||
|
||||
has: function (name, category, scope) {
|
||||
if (scope in this.data) {
|
||||
if (category in this.data[scope]) {
|
||||
@@ -65,7 +65,7 @@ _.extend(Espo.Language.prototype, {
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
||||
|
||||
translateOption: function (value, field, scope) {
|
||||
var translation = this.translate(field, 'options', scope);
|
||||
if (typeof translation != 'object') {
|
||||
@@ -73,9 +73,9 @@ _.extend(Espo.Language.prototype, {
|
||||
}
|
||||
return translation[value] || value;
|
||||
},
|
||||
|
||||
|
||||
loadFromCache: function () {
|
||||
|
||||
|
||||
if (this.cache) {
|
||||
var cached = this.cache.get('app', 'language');
|
||||
if (cached) {
|
||||
@@ -85,19 +85,19 @@ _.extend(Espo.Language.prototype, {
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
|
||||
clearCache: function () {
|
||||
if (this.cache) {
|
||||
this.cache.clear('app', 'language');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
storeToCache: function () {
|
||||
if (this.cache) {
|
||||
this.cache.set('app', 'language', this.data);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
load: function (callback, disableCache) {
|
||||
this.once('sync', callback);
|
||||
|
||||
@@ -125,7 +125,7 @@ _.extend(Espo.Language.prototype, {
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
}, Backbone.Events);
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
this.container = 'body'
|
||||
this.onRemove = function () {};
|
||||
|
||||
var params = ['className', 'backdrop', 'closeButton', 'header', 'body', 'width', 'height', 'buttons', 'removeOnClose', 'graggable', 'container', 'onRemove'];
|
||||
var params = ['className', 'backdrop', 'keyboard', 'closeButton', 'header', 'body', 'width', 'height', 'buttons', 'removeOnClose', 'graggable', 'container', 'onRemove'];
|
||||
params.forEach(function (param) {
|
||||
if (param in options) {
|
||||
this[param] = options[param];
|
||||
@@ -124,6 +124,7 @@
|
||||
Dialog.prototype.show = function () {
|
||||
this.$el.modal({
|
||||
backdrop: this.backdrop,
|
||||
keyboard: this.keyboard
|
||||
});
|
||||
};
|
||||
Dialog.prototype.hide = function () {
|
||||
|
||||
@@ -45,26 +45,37 @@ Espo.define('Views.Detail', 'Views.Main', function (Dep) {
|
||||
},
|
||||
|
||||
addUnfollowButtonToMenu: function () {
|
||||
this.menu.buttons.unshift({
|
||||
name: 'unfollow',
|
||||
label: 'Followed',
|
||||
style: 'success',
|
||||
action: 'unfollow'
|
||||
});
|
||||
|
||||
var index = -1;
|
||||
this.menu.buttons.forEach(function (data, i) {
|
||||
if (data.name == 'follow') {
|
||||
var index = i;
|
||||
index = i;
|
||||
return;
|
||||
}
|
||||
}, this);
|
||||
if (~index) {
|
||||
this.menu.buttons.splice(index, 1);
|
||||
}
|
||||
|
||||
this.menu.buttons.unshift({
|
||||
name: 'unfollow',
|
||||
label: 'Followed',
|
||||
style: 'success',
|
||||
action: 'unfollow'
|
||||
});
|
||||
},
|
||||
|
||||
addFollowButtonToMenu: function () {
|
||||
var index = -1;
|
||||
this.menu.buttons.forEach(function (data, i) {
|
||||
if (data.name == 'unfollow') {
|
||||
index = i;
|
||||
return;
|
||||
}
|
||||
}, this);
|
||||
if (~index) {
|
||||
this.menu.buttons.splice(index, 1);
|
||||
}
|
||||
|
||||
this.menu.buttons.unshift({
|
||||
name: 'follow',
|
||||
label: 'Follow',
|
||||
@@ -72,17 +83,6 @@ Espo.define('Views.Detail', 'Views.Main', function (Dep) {
|
||||
icon: 'glyphicon glyphicon-share-alt',
|
||||
action: 'follow'
|
||||
});
|
||||
|
||||
var index = -1;
|
||||
this.menu.buttons.forEach(function (data, i) {
|
||||
if (data.name == 'unfollow') {
|
||||
var index = i;
|
||||
return;
|
||||
}
|
||||
}, this);
|
||||
if (~index) {
|
||||
this.menu.buttons.splice(index, 1);
|
||||
}
|
||||
},
|
||||
|
||||
setup: function () {
|
||||
@@ -90,39 +90,37 @@ Espo.define('Views.Detail', 'Views.Main', function (Dep) {
|
||||
|
||||
if (this.getMetadata().get('scopes.' + this.scope + '.stream')) {
|
||||
if (this.model.has('isFollowed')) {
|
||||
if (this.model.get('isFollowed')) {
|
||||
this.addUnfollowButtonToMenu();
|
||||
} else {
|
||||
this.addFollowButtonToMenu();
|
||||
}
|
||||
this.handleFollowButton();
|
||||
} else {
|
||||
this.once('after:render', function () {
|
||||
var proceed = function () {
|
||||
if (this.model.get('isFollowed')) {
|
||||
this.addUnfollowButton();
|
||||
this.addUnfollowButtonToMenu();
|
||||
} else {
|
||||
this.addFollowButton();
|
||||
this.addFollowButtonToMenu();
|
||||
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
if (this.model.has('isFollowed')) {
|
||||
proceed();
|
||||
this.handleFollowButton();
|
||||
} else {
|
||||
this.listenToOnce(this.model, 'sync', function () {
|
||||
if (this.model.has('isFollowed')) {
|
||||
proceed();
|
||||
this.handleFollowButton();
|
||||
}
|
||||
}.bind(this));
|
||||
}, this);
|
||||
}
|
||||
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleFollowButton: function () {
|
||||
if (this.model.get('isFollowed')) {
|
||||
if (this.isRendered()) {
|
||||
this.addUnfollowButton();
|
||||
}
|
||||
this.addUnfollowButtonToMenu();
|
||||
} else {
|
||||
if (this.isRendered()) {
|
||||
this.addFollowButton();
|
||||
}
|
||||
this.addFollowButtonToMenu();
|
||||
}
|
||||
},
|
||||
|
||||
addFollowButton: function () {
|
||||
$el = $('<button>').addClass('btn btn-default action')
|
||||
.attr('data-action', 'follow')
|
||||
@@ -145,7 +143,11 @@ Espo.define('Views.Detail', 'Views.Main', function (Dep) {
|
||||
type: 'PUT',
|
||||
success: function () {
|
||||
$el.remove();
|
||||
this.addUnfollowButton();
|
||||
this.model.set('isFollowed', true);
|
||||
this.handleFollowButton();
|
||||
}.bind(this),
|
||||
error: function () {
|
||||
$el.removeClass('disabled');
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
@@ -158,7 +160,11 @@ Espo.define('Views.Detail', 'Views.Main', function (Dep) {
|
||||
type: 'DELETE',
|
||||
success: function () {
|
||||
$el.remove();
|
||||
this.addFollowButton();
|
||||
this.model.set('isFollowed', false);
|
||||
this.handleFollowButton();
|
||||
}.bind(this),
|
||||
error: function () {
|
||||
$el.removeClass('disabled');
|
||||
}.bind(this)
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/************************************************************************
|
||||
* 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.EmailAccount.Fields.TestConnection', 'Views.Fields.Base', function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
readOnly: true,
|
||||
|
||||
_template: '<button class="btn btn-default disabled" data-action="testConnection">{{translate \'Test Connection\' scope=\'EmailAccount\'}}</button>',
|
||||
|
||||
url: 'EmailAccount/action/testConnection',
|
||||
|
||||
events: {
|
||||
'click [data-action="testConnection"]': function () {
|
||||
this.test();
|
||||
},
|
||||
},
|
||||
|
||||
fetch: function () {
|
||||
return {};
|
||||
},
|
||||
|
||||
checkAvailability: function () {
|
||||
if (this.model.get('host')) {
|
||||
this.$el.find('button').removeClass('disabled');
|
||||
} else {
|
||||
this.$el.find('button').addClass('disabled');
|
||||
}
|
||||
},
|
||||
|
||||
afterRender: function () {
|
||||
this.checkAvailability();
|
||||
|
||||
this.stopListening(this.model, 'change:host');
|
||||
this.listenTo(this.model, 'change:host', function () {
|
||||
this.checkAvailability();
|
||||
}, this);
|
||||
},
|
||||
|
||||
getData: function () {
|
||||
var data = {
|
||||
'host': this.model.get('host'),
|
||||
'port': this.model.get('port'),
|
||||
'ssl': this.model.get('ssl'),
|
||||
'username': this.model.get('username'),
|
||||
'password': this.model.get('password') || null,
|
||||
'id': this.model.id
|
||||
};
|
||||
return data;
|
||||
},
|
||||
|
||||
|
||||
test: function () {
|
||||
var data = this.getData();
|
||||
|
||||
var $btn = this.$el.find('button');
|
||||
|
||||
$btn.addClass('disabled');
|
||||
|
||||
Espo.Ui.notify(this.translate('pleaseWait', 'messages'));
|
||||
|
||||
$.ajax({
|
||||
url: this.url,
|
||||
type: 'POST',
|
||||
data: JSON.stringify(data),
|
||||
error: function (xhr, status) {
|
||||
var statusReason = xhr.getResponseHeader('X-Status-Reason') || '';
|
||||
statusReason = statusReason.replace(/ $/, '');
|
||||
statusReason = statusReason.replace(/,$/, '');
|
||||
|
||||
var msg = this.translate('Error') + ' ' + xhr.status;
|
||||
if (statusReason) {
|
||||
msg += ': ' + statusReason;
|
||||
}
|
||||
Espo.Ui.error(msg);
|
||||
console.error(msg);
|
||||
xhr.errorIsHandled = true;
|
||||
$btn.removeClass('disabled');
|
||||
}.bind(this)
|
||||
}).done(function () {
|
||||
$btn.removeClass('disabled');
|
||||
Espo.Ui.success(this.translate('connectionIsOk', 'messages', 'EmailAccount'));
|
||||
}.bind(this));
|
||||
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -23,7 +23,9 @@ Espo.define('Views.EmailAccount.Record.List', 'Views.Record.List', function (Dep
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
allowQuickEdit: false,
|
||||
quickDetailDisabled: true,
|
||||
|
||||
quickEditDisabled: true,
|
||||
|
||||
checkAllResultDisabled: true,
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ Espo.define('Views.Email.Detail', 'Views.Detail', function (Dep) {
|
||||
};
|
||||
|
||||
var subject = this.model.get('name');
|
||||
if (subject.indexOf('Re:') !== 0) {
|
||||
if (subject.toUpperCase().indexOf('RE:') !== 0) {
|
||||
attributes['name'] = 'Re: ' + subject;
|
||||
} else {
|
||||
attributes['name'] = subject;
|
||||
|
||||
@@ -27,7 +27,9 @@ Espo.define('Views.Extension.Record.List', 'Views.Record.List', function (Dep) {
|
||||
|
||||
checkboxes: false,
|
||||
|
||||
allowQuickEdit: false,
|
||||
quickDetailDisabled: true,
|
||||
|
||||
quickEditDisabled: true,
|
||||
|
||||
massActionList: []
|
||||
|
||||
|
||||
@@ -287,20 +287,26 @@ Espo.define('Views.Fields.Email', 'Views.Fields.Base', function (Dep) {
|
||||
fetch: function () {
|
||||
var data = {};
|
||||
|
||||
var adderssData = this.fetchEmailAddressData();
|
||||
var adderssData = this.fetchEmailAddressData() || [];
|
||||
data[this.dataFieldName] = adderssData;
|
||||
data[this.name] = null;
|
||||
|
||||
var primaryIndex = 0;
|
||||
(adderssData || []).forEach(function (item, i) {
|
||||
adderssData.forEach(function (item, i) {
|
||||
if (item.primary) {
|
||||
primaryIndex = i;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (adderssData.length && primaryIndex > 0) {
|
||||
var t = adderssData[0];
|
||||
adderssData[0] = adderssData[primaryIndex];
|
||||
adderssData[primaryIndex] = t;
|
||||
}
|
||||
|
||||
if (adderssData.length) {
|
||||
data[this.name] = adderssData[primaryIndex].emailAddress;
|
||||
data[this.name] = adderssData[0].emailAddress;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
@@ -225,19 +225,26 @@ Espo.define('Views.Fields.Phone', 'Views.Fields.Base', function (Dep) {
|
||||
fetch: function () {
|
||||
var data = {};
|
||||
|
||||
var adderssData = this.fetchPhoneNumberData();
|
||||
var adderssData = this.fetchPhoneNumberData() || [];
|
||||
data[this.dataFieldName] = adderssData;
|
||||
data[this.name] = null;
|
||||
|
||||
var primaryIndex = 0;
|
||||
(adderssData || []).forEach(function (item, i) {
|
||||
adderssData.forEach(function (item, i) {
|
||||
if (item.primary) {
|
||||
primaryIndex = i;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (adderssData.length && primaryIndex > 0) {
|
||||
var t = adderssData[0];
|
||||
adderssData[0] = adderssData[primaryIndex];
|
||||
adderssData[primaryIndex] = t;
|
||||
}
|
||||
|
||||
if (adderssData.length) {
|
||||
data[this.name] = adderssData[primaryIndex].phoneNumber;
|
||||
data[this.name] = adderssData[0].phoneNumber;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
@@ -80,8 +80,8 @@ Espo.define('Views.Fields.Text', 'Views.Fields.Base', function (Dep) {
|
||||
|
||||
afterRender: function () {
|
||||
Dep.prototype.afterRender.call(this);
|
||||
var text = this.model.get(this.name);
|
||||
if (this.mode == 'edit') {
|
||||
var text = this.getValueForDisplay();
|
||||
if (text) {
|
||||
this.$element.val(text);
|
||||
}
|
||||
|
||||
@@ -62,6 +62,14 @@ Espo.define('Views.Fields.Wysiwyg', ['Views.Fields.Text', 'lib!Summernote'], fun
|
||||
});
|
||||
},
|
||||
|
||||
getValueForDisplay: function () {
|
||||
var value = Dep.prototype.getValueForDisplay.call(this);
|
||||
if (this.mode == 'edit' && value) {
|
||||
value = value.replace(/<[\/]{0,1}(base|BASE)[^><]*>/g, '');
|
||||
}
|
||||
return value;
|
||||
},
|
||||
|
||||
afterRender: function () {
|
||||
Dep.prototype.afterRender.call(this);
|
||||
|
||||
|
||||
@@ -23,7 +23,9 @@ Espo.define('Views.Import.Record.List', 'Views.Record.List', function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
allowQuickEdit: false,
|
||||
quickDetailDisabled: true,
|
||||
|
||||
quickEditDisabled: true,
|
||||
|
||||
checkAllResultDisabled: true,
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ Espo.define('Views.Modal', 'View', function (Dep) {
|
||||
|
||||
width: false,
|
||||
|
||||
escapeDisabled: false,
|
||||
|
||||
init: function () {
|
||||
var id = this.cssName + '-container-' + Math.floor((Math.random() * 10000) + 1).toString();
|
||||
var containerSelector = this.containerSelector = '#' + id;
|
||||
@@ -71,6 +73,7 @@ Espo.define('Views.Modal', 'View', function (Dep) {
|
||||
body: '',
|
||||
buttons: buttons,
|
||||
width: this.width,
|
||||
keyboard: !this.escapeDisabled,
|
||||
onRemove: function () {
|
||||
this.remove();
|
||||
}.bind(this)
|
||||
|
||||
@@ -37,6 +37,8 @@ Espo.define('Views.Modals.Edit', 'Views.Modal', function (Dep) {
|
||||
|
||||
columnCount: 1,
|
||||
|
||||
escapeDisabled: true,
|
||||
|
||||
setup: function () {
|
||||
|
||||
var self = this;
|
||||
|
||||
@@ -40,7 +40,11 @@ Espo.define('Views.Notifications.Items.EmailReceived', 'Views.Notifications.Noti
|
||||
this.userId = data.userId;
|
||||
|
||||
this.messageData['entityType'] = Espo.Utils.upperCaseFirst((this.translate(data.entityType, 'scopeNames') || '').toLowerCase());
|
||||
this.messageData['from'] = '<a href="#' + data.personEntityType + '/view/' + data.personEntityId + '">' + data.personEntityName + '</a>';
|
||||
if (data.personEntityId) {
|
||||
this.messageData['from'] = '<a href="#' + data.personEntityType + '/view/' + data.personEntityId + '">' + data.personEntityName + '</a>';
|
||||
} else {
|
||||
this.messageData['from'] = data.fromString || this.translate('empty address');
|
||||
}
|
||||
|
||||
this.emailId = data.emailId;
|
||||
this.emailName = data.emailName;
|
||||
|
||||
@@ -90,7 +90,7 @@ Espo.define('Views.OutboundEmail.Fields.TestSend', 'Views.Fields.Base', function
|
||||
type: 'POST',
|
||||
data: JSON.stringify(data),
|
||||
error: function (xhr, status) {
|
||||
var statusReason = xhr.getResponseHeader('X-Status-Reason');
|
||||
var statusReason = xhr.getResponseHeader('X-Status-Reason') || '';
|
||||
statusReason = statusReason.replace(/ $/, '');
|
||||
statusReason = statusReason.replace(/,$/, '');
|
||||
|
||||
|
||||
@@ -184,7 +184,9 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
|
||||
|
||||
exportAction: true,
|
||||
|
||||
allowQuickEdit: true,
|
||||
quickDetailDisabled: false,
|
||||
|
||||
quickEditDisabled: false,
|
||||
|
||||
/**
|
||||
* @param {array} Columns layout. Will be convered in 'Bull' typed layout for a fields rendering.
|
||||
@@ -847,23 +849,27 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
|
||||
var id = data.id;
|
||||
if (!id) return;
|
||||
|
||||
this.notify('Loading...');
|
||||
this.createView('quickDetail', 'Modals.Detail', {
|
||||
scope: this.scope,
|
||||
id: id
|
||||
}, function (view) {
|
||||
view.once('after:render', function () {
|
||||
Espo.Ui.notify(false);
|
||||
});
|
||||
view.render();
|
||||
view.once('after:save', function () {
|
||||
console.log(2);
|
||||
var model = this.collection.get(id);
|
||||
if (model) {
|
||||
model.fetch();
|
||||
}
|
||||
}, this);
|
||||
}.bind(this));
|
||||
if (!this.quickDetailDisabled) {
|
||||
this.notify('Loading...');
|
||||
this.createView('quickDetail', 'Modals.Detail', {
|
||||
scope: this.scope,
|
||||
id: id
|
||||
}, function (view) {
|
||||
view.once('after:render', function () {
|
||||
Espo.Ui.notify(false);
|
||||
});
|
||||
view.render();
|
||||
view.once('after:save', function () {
|
||||
console.log(2);
|
||||
var model = this.collection.get(id);
|
||||
if (model) {
|
||||
model.fetch();
|
||||
}
|
||||
}, this);
|
||||
}.bind(this));
|
||||
} else {
|
||||
this.getRouter().navigate('#' + this.scope + '/view/' + id, {trigger: true});
|
||||
}
|
||||
},
|
||||
|
||||
actionQuickEdit: function (d) {
|
||||
@@ -871,7 +877,7 @@ Espo.define('Views.Record.List', 'View', function (Dep) {
|
||||
var id = d.id;
|
||||
if (!id) return;
|
||||
|
||||
if (this.allowQuickEdit) {
|
||||
if (!this.quickEditDisabled) {
|
||||
this.notify('Loading...');
|
||||
this.createView('quickEdit', 'Modals.Edit', {
|
||||
scope: this.scope,
|
||||
|
||||
@@ -23,7 +23,9 @@ Espo.define('Views.Role.Record.List', 'Views.Record.List', function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
allowQuickEdit: false,
|
||||
quickDetailDisabled: true,
|
||||
|
||||
quickEditDisabled: true,
|
||||
|
||||
massActionList: ['remove'],
|
||||
|
||||
|
||||
@@ -17,15 +17,17 @@
|
||||
*
|
||||
* 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.ScheduledJob.Record.List', 'Views.Record.List', function (Dep) {
|
||||
************************************************************************/
|
||||
|
||||
Espo.define('Views.ScheduledJob.Record.List', 'Views.Record.List', function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
allowQuickEdit: false,
|
||||
|
||||
});
|
||||
|
||||
|
||||
quickDetailDisabled: true,
|
||||
|
||||
quickEditDisabled: true,
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -61,6 +61,11 @@ Espo.define('Views.Stream.Notes.EmailReceived', 'Views.Stream.Note', function (D
|
||||
this.messageName += 'From';
|
||||
this.messageData['from'] = '<a href="#'+data.personEntityType+'/view/' + data.personEntityId + '">' + data.personEntityName + '</a>';
|
||||
}
|
||||
|
||||
if (this.model.get('parentType') === data.personEntityType && this.model.get('parentId') == data.personEntityId) {
|
||||
this.isThis = true;
|
||||
}
|
||||
|
||||
if (this.isThis) {
|
||||
this.messageName += 'This';
|
||||
}
|
||||
|
||||
@@ -23,7 +23,9 @@ Espo.define('Views.Team.Record.List', 'Views.Record.List', function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
allowQuickEdit: false,
|
||||
quickDetailDisabled: true,
|
||||
|
||||
quickEditDisabled: true,
|
||||
|
||||
massActionList: ['remove'],
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ Espo.define('Views.User.Record.List', 'Views.Record.List', function (Dep) {
|
||||
|
||||
return Dep.extend({
|
||||
|
||||
allowQuickEdit: false,
|
||||
quickEditDisabled: true,
|
||||
|
||||
massActionList: ['remove', 'massUpdate', 'export'],
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<div id="msg-box" class="alert hide"></div>
|
||||
|
||||
<form id="nav">
|
||||
<form id="nav" autocomplete="off">
|
||||
<div class="row">
|
||||
<div class=" col-md-6">
|
||||
<div class="row">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="panel-body body">
|
||||
<div id="msg-box" class="alert hide"></div>
|
||||
<div class="loading-icon hide"></div>
|
||||
<form id="nav">
|
||||
<form id="nav" autocomplete="off">
|
||||
<div class="row">
|
||||
<div class="col-md-8" style="width:100%" >
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "espocrm",
|
||||
"version": "3.2.0",
|
||||
"version": "3.2.2",
|
||||
"description": "",
|
||||
"main": "index.php",
|
||||
"repository": {
|
||||
|
||||
Reference in New Issue
Block a user