diff --git a/Gruntfile.js b/Gruntfile.js index b7da2dd889..2fbc6ce5f8 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -80,6 +80,7 @@ module.exports = function (grunt) { 'client/src/theme-manager.js', 'client/src/session-storage.js', 'client/src/view-helper.js', + 'client/src/page-title.js', 'client/src/app.js' ]; diff --git a/application/Espo/Core/defaults/config.php b/application/Espo/Core/defaults/config.php index 460a1b72c5..14f07d1913 100644 --- a/application/Espo/Core/defaults/config.php +++ b/application/Espo/Core/defaults/config.php @@ -181,5 +181,6 @@ return [ 'useWebSocket' => false, 'auth2FAMethodList' => ['Totp'], 'personNameFormat' => 'firstLast', + 'newNotificationCountInTitle' => false, 'isInstalled' => false, ]; diff --git a/application/Espo/Resources/i18n/en_US/Settings.json b/application/Espo/Resources/i18n/en_US/Settings.json index 11d277e70f..48fa420b39 100644 --- a/application/Espo/Resources/i18n/en_US/Settings.json +++ b/application/Espo/Resources/i18n/en_US/Settings.json @@ -85,6 +85,7 @@ "addressFormat": "Address Format", "personNameFormat": "Person Name Format", "notificationSoundsDisabled": "Disable Notification Sounds", + "newNotificationCountInTitle": "Display new notification number in page title", "applicationName": "Application Name", "calendarEntityList": "Calendar Entity List", "mentionEmailNotifications": "Send email notifications about mentions in posts", diff --git a/application/Espo/Resources/layouts/Settings/notifications.json b/application/Espo/Resources/layouts/Settings/notifications.json index b029926759..e46e3639d7 100644 --- a/application/Espo/Resources/layouts/Settings/notifications.json +++ b/application/Espo/Resources/layouts/Settings/notifications.json @@ -2,7 +2,8 @@ { "label": "In-app Notifications", "rows": [ - [{"name": "assignmentNotificationsEntityList"}, false] + [{"name": "assignmentNotificationsEntityList"}, false], + [{"name": "newNotificationCountInTitle"}, false] ] }, { diff --git a/application/Espo/Resources/metadata/entityDefs/Settings.json b/application/Espo/Resources/metadata/entityDefs/Settings.json index 88e0c9f7c3..33fc1f2962 100644 --- a/application/Espo/Resources/metadata/entityDefs/Settings.json +++ b/application/Espo/Resources/metadata/entityDefs/Settings.json @@ -359,6 +359,9 @@ "type": "multiEnum", "options": ["Post", "Status", "EmailReceived"] }, + "newNotificationCountInTitle": { + "type": "bool" + }, "b2cMode": { "type": "bool", "default": false, diff --git a/client/src/app.js b/client/src/app.js index a0de9c7fd5..44e60b9cff 100644 --- a/client/src/app.js +++ b/client/src/app.js @@ -54,6 +54,7 @@ define( 'web-socket-manager', 'ajax', 'number', + 'page-title', ], function ( Ui, @@ -79,7 +80,8 @@ define( ViewHelper, WebSocketManager, Ajax, - NumberUtil + NumberUtil, + PageTitle ) { var App = function (options, callback) { @@ -420,6 +422,7 @@ define( helper.appParams = this.appParams; helper.webSocketManager = this.webSocketManager; helper.numberUtil = this.numberUtil; + helper.pageTitle = new PageTitle(this.settings); this.viewLoader = function (viewName, callback) { Espo.require(Espo.Utils.composeViewClassName(viewName), callback); diff --git a/client/src/page-title.js b/client/src/page-title.js new file mode 100644 index 0000000000..8a96018166 --- /dev/null +++ b/client/src/page-title.js @@ -0,0 +1,67 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014-2020 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko + * Website: https://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/. + * + * 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 General Public License version 3. + * + * In accordance with Section 7(b) of the GNU General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. + ************************************************************************/ + +define('page-title', [], function () { + + var PageTitle = function (config) { + this.displayNotificationNumber = config.get('newNotificationCountInTitle') || false; + + this.title = $('head title').text() || ''; + + this.notificationNumber = 0; + }; + + _.extend(PageTitle.prototype, { + setTitle: function (title) { + this.title = title; + this.update(); + }, + + setNotificationNumber: function (notificationNumber) { + this.notificationNumber = notificationNumber; + if (this.displayNotificationNumber) { + this.update(); + } + }, + + update: function () { + var value = ''; + if (this.displayNotificationNumber && this.notificationNumber) { + value = '(' + this.notificationNumber.toString() + ')'; + if (this.title) value += ' '; + } + + value += this.title; + + $('head title').text(value) + }, + + }); + + return PageTitle; +}); diff --git a/client/src/view.js b/client/src/view.js index f827317835..24d7fe9df7 100644 --- a/client/src/view.js +++ b/client/src/view.js @@ -167,7 +167,7 @@ define('view', [], function () { }, setPageTitle: function (title) { - $('head title').text(title); + this.getHelper().pageTitle.setTitle(title); }, translate: function (label, category, scope) { diff --git a/client/src/views/notification/badge.js b/client/src/views/notification/badge.js index 22436a33bd..4e4bc3f43d 100644 --- a/client/src/views/notification/badge.js +++ b/client/src/views/notification/badge.js @@ -129,11 +129,15 @@ define('views/notification/badge', 'view', function (Dep) { this.$badge.attr('title', this.translate('New notifications') + ': ' + count); this.$number.removeClass('hidden').html(count.toString()); + + this.getHelper().pageTitle.setNotificationNumber(count); }, hideNotRead: function () { this.$badge.attr('title', this.translate('Notifications')); this.$number.addClass('hidden').html(''); + + this.getHelper().pageTitle.setNotificationNumber(0); }, checkBypass: function () {