email: notify user when added

This commit is contained in:
Yuri Kuznetsov
2024-10-17 16:35:45 +03:00
parent bc2bb3d4a2
commit 7d18ed3222
7 changed files with 125 additions and 6 deletions

View File

@@ -30,21 +30,29 @@
namespace Espo\Core\Notification;
use Espo\Core\ORM\EntityManager;
use Espo\Core\Utils\Config;
use Espo\Entities\Preferences;
class UserEnabledChecker
{
/** @var array<string, bool> */
private $assignmentCache = [];
public function __construct(private EntityManager $entityManager)
{}
public function __construct(
private EntityManager $entityManager,
private Config $config,
) {}
public function checkAssignment(string $entityType, string $userId): bool
{
if (!in_array($entityType, $this->config->get('assignmentNotificationsEntityList', []))) {
return false;
}
$key = $entityType . '_' . $userId;
if (!array_key_exists($key, $this->assignmentCache)) {
$preferences = $this->entityManager->getEntity('Preferences', $userId);
$preferences = $this->entityManager->getEntityById(Preferences::ENTITY_TYPE, $userId);
$isEnabled = false;

View File

@@ -70,7 +70,10 @@ class Notification extends Entity
return $this->get('data');
}
public function setData(stdClass $data): self
/**
* @param stdClass|array<string, mixed> $data
*/
public function setData(stdClass|array $data): self
{
$this->set('data', $data);

View File

@@ -509,7 +509,8 @@
"notificationMessages": {
"assign": "{entityType} {entity} has been assigned to you",
"emailReceived": "Email received from {from}",
"entityRemoved": "{user} removed {entityType} {entity}"
"entityRemoved": "{user} removed {entityType} {entity}",
"emailInbox": "{user} added email {entity} to your inbox"
},
"streamMessages": {
"post": "{user} posted on {entityType} {entity}",

View File

@@ -4,6 +4,7 @@
"aclPortal": "acl-portal/notification",
"collection": "collections/note",
"itemViews": {
"System": "views/notification/items/system"
"System": "views/notification/items/system",
"EmailInbox": "views/notification/items/email-inbox"
}
}

View File

@@ -37,8 +37,11 @@ use Espo\Core\Api\ResponseComposer;
use Espo\Core\Exceptions\BadRequest;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Exceptions\NotFound;
use Espo\Core\Field\LinkParent;
use Espo\Core\Notification\UserEnabledChecker;
use Espo\Core\Record\EntityProvider;
use Espo\Entities\Email;
use Espo\Entities\Notification;
use Espo\Entities\User;
use Espo\ORM\EntityManager;
use RuntimeException;
@@ -52,6 +55,8 @@ class PostUsers implements Action
private EntityProvider $entityProvider,
private Acl $acl,
private EntityManager $entityManager,
private UserEnabledChecker $userEnabledChecker,
private User $user,
) {}
public function process(Request $request): Response
@@ -87,6 +92,8 @@ class PostUsers implements Action
}
$relation->relate($user);
$this->processNotify($email, $user);
}
return ResponseComposer::json(true);
@@ -137,4 +144,25 @@ class PostUsers implements Action
return $users;
}
private function processNotify(Email $email, User $user): void
{
if (!$this->userEnabledChecker->checkAssignment(Email::ENTITY_TYPE, $user->getId())) {
return;
}
$notification = $this->entityManager->getRDBRepositoryByClass(Notification::class)->getNew();
$notification
->setType('EmailInbox')
->setRelated(LinkParent::createFromEntity($email))
->setUserId($user->getId())
->setData([
'emailName' => $email->getSubject(),
'userId' => $this->user->getId(),
'userName' => $this->user->getName(),
]);
$this->entityManager->saveEntity($notification);
}
}

View File

@@ -96,6 +96,7 @@ class HookProcessor
$notificator = $this->getNotificator($entityType);
if (!$notificator instanceof AssignmentNotificator) {
// @todo Remove in v9.0.
// For backward compatibility.
$notificator->process($entity, $options);

View File

@@ -0,0 +1,77 @@
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM Open Source CRM application.
* Copyright (C) 2014-2024 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
import BaseNotificationItemView from 'views/notification/items/base';
class EmailInboxNotificationItemView extends BaseNotificationItemView {
template = 'notification/items/system'
messageName = 'emailInbox'
// language=Handlebars
templateContent = `
<div class="stream-head-container">
<div class="pull-left">{{{avatar}}}</div>
<div class="stream-head-text-container">
<span class="text-muted message">{{{message}}}</span>
</div>
</div>
<div class="stream-date-container">
<span class="text-muted small">{{{createdAt}}}</span>
</div>
`
setup() {
/** @type {{userId: string, userName: string, emailName: string}} */
const data = this.model.attributes.data || {};
this.userId = data.userId;
this.messageData['entityType'] = this.translateEntityType('Email');
const entity = document.createElement('a');
entity.href = `#Email/view/${this.model.attributes.relatedId}`;
entity.dataset.id = this.model.attributes.relatedId;
entity.dataset.scope = 'Email';
entity.innerText = data.emailName;
const user = document.createElement('a');
user.href = `#User/view/${data.userId}`;
user.dataset.id = data.userId;
user.dataset.scope = 'User';
user.innerText = data.userName;
this.messageData['entity'] = entity;
this.messageData['user'] = user;
this.createMessage();
}
}
export default EmailInboxNotificationItemView;