Browse Source

Aug 17: [ADD] Initital Commits 'odoo_mail_management'

pull/332/merge
Cybrosys Technologies 8 months ago
parent
commit
aafefef03a
  1. 46
      odoo_mail_management/README.rst
  2. 22
      odoo_mail_management/__init__.py
  3. 55
      odoo_mail_management/__manifest__.py
  4. 10
      odoo_mail_management/data/mail_icon_data.xml
  5. 7
      odoo_mail_management/doc/RELEASE_NOTES.md
  6. 26
      odoo_mail_management/models/__init__.py
  7. 46
      odoo_mail_management/models/ir_attachment.py
  8. 34
      odoo_mail_management/models/mail_attachment.py
  9. 69
      odoo_mail_management/models/mail_icon.py
  10. 190
      odoo_mail_management/models/mail_mail.py
  11. 46
      odoo_mail_management/models/res_config_settings.py
  12. 3
      odoo_mail_management/security/ir.model.access.csv
  13. BIN
      odoo_mail_management/static/description/assets/icons/check.png
  14. BIN
      odoo_mail_management/static/description/assets/icons/chevron.png
  15. BIN
      odoo_mail_management/static/description/assets/icons/cogs.png
  16. BIN
      odoo_mail_management/static/description/assets/icons/consultation.png
  17. BIN
      odoo_mail_management/static/description/assets/icons/ecom-black.png
  18. BIN
      odoo_mail_management/static/description/assets/icons/education-black.png
  19. BIN
      odoo_mail_management/static/description/assets/icons/hotel-black.png
  20. BIN
      odoo_mail_management/static/description/assets/icons/license.png
  21. BIN
      odoo_mail_management/static/description/assets/icons/lifebuoy.png
  22. BIN
      odoo_mail_management/static/description/assets/icons/manufacturing-black.png
  23. BIN
      odoo_mail_management/static/description/assets/icons/pos-black.png
  24. BIN
      odoo_mail_management/static/description/assets/icons/puzzle.png
  25. BIN
      odoo_mail_management/static/description/assets/icons/restaurant-black.png
  26. BIN
      odoo_mail_management/static/description/assets/icons/service-black.png
  27. BIN
      odoo_mail_management/static/description/assets/icons/trading-black.png
  28. BIN
      odoo_mail_management/static/description/assets/icons/training.png
  29. BIN
      odoo_mail_management/static/description/assets/icons/update.png
  30. BIN
      odoo_mail_management/static/description/assets/icons/user.png
  31. BIN
      odoo_mail_management/static/description/assets/icons/wrench.png
  32. BIN
      odoo_mail_management/static/description/assets/misc/categories.png
  33. BIN
      odoo_mail_management/static/description/assets/misc/check-box.png
  34. BIN
      odoo_mail_management/static/description/assets/misc/compass.png
  35. BIN
      odoo_mail_management/static/description/assets/misc/corporate.png
  36. BIN
      odoo_mail_management/static/description/assets/misc/customer-support.png
  37. BIN
      odoo_mail_management/static/description/assets/misc/cybrosys-logo.png
  38. BIN
      odoo_mail_management/static/description/assets/misc/features.png
  39. BIN
      odoo_mail_management/static/description/assets/misc/logo.png
  40. BIN
      odoo_mail_management/static/description/assets/misc/pictures.png
  41. BIN
      odoo_mail_management/static/description/assets/misc/pie-chart.png
  42. BIN
      odoo_mail_management/static/description/assets/misc/right-arrow.png
  43. BIN
      odoo_mail_management/static/description/assets/misc/star.png
  44. BIN
      odoo_mail_management/static/description/assets/misc/support.png
  45. BIN
      odoo_mail_management/static/description/assets/misc/whatsapp.png
  46. BIN
      odoo_mail_management/static/description/assets/modules/module01.png
  47. BIN
      odoo_mail_management/static/description/assets/modules/module02.png
  48. BIN
      odoo_mail_management/static/description/assets/modules/module03.png
  49. BIN
      odoo_mail_management/static/description/assets/modules/module04.png
  50. BIN
      odoo_mail_management/static/description/assets/modules/module05.png
  51. BIN
      odoo_mail_management/static/description/assets/modules/module06.png
  52. BIN
      odoo_mail_management/static/description/assets/screenshots/1.png
  53. BIN
      odoo_mail_management/static/description/assets/screenshots/10.png
  54. BIN
      odoo_mail_management/static/description/assets/screenshots/11.png
  55. BIN
      odoo_mail_management/static/description/assets/screenshots/12.png
  56. BIN
      odoo_mail_management/static/description/assets/screenshots/13.png
  57. BIN
      odoo_mail_management/static/description/assets/screenshots/14.png
  58. BIN
      odoo_mail_management/static/description/assets/screenshots/2.png
  59. BIN
      odoo_mail_management/static/description/assets/screenshots/3.png
  60. BIN
      odoo_mail_management/static/description/assets/screenshots/4.png
  61. BIN
      odoo_mail_management/static/description/assets/screenshots/5.png
  62. BIN
      odoo_mail_management/static/description/assets/screenshots/6.png
  63. BIN
      odoo_mail_management/static/description/assets/screenshots/7.png
  64. BIN
      odoo_mail_management/static/description/assets/screenshots/8.png
  65. BIN
      odoo_mail_management/static/description/assets/screenshots/9.png
  66. BIN
      odoo_mail_management/static/description/assets/screenshots/hero.gif
  67. BIN
      odoo_mail_management/static/description/banner.jpg
  68. BIN
      odoo_mail_management/static/description/icon.png
  69. 751
      odoo_mail_management/static/description/index.html
  70. 1331
      odoo_mail_management/static/src/css/main.css
  71. 1
      odoo_mail_management/static/src/img/archive_black_24dp.svg
  72. 1
      odoo_mail_management/static/src/img/attachment.svg
  73. 1
      odoo_mail_management/static/src/img/calendar_month_FILL0_wght400_GRAD0_opsz48.svg
  74. 1
      odoo_mail_management/static/src/img/clear_black_24dp.svg
  75. 1
      odoo_mail_management/static/src/img/contact_page_FILL0_wght400_GRAD0_opsz48.svg
  76. 1
      odoo_mail_management/static/src/img/delete_black_24dp.svg
  77. 1
      odoo_mail_management/static/src/img/edit_square_FILL0_wght400_GRAD0_opsz48.svg
  78. 1
      odoo_mail_management/static/src/img/expand_icon.svg
  79. BIN
      odoo_mail_management/static/src/img/logo.png
  80. 1
      odoo_mail_management/static/src/img/menu_black_24dp.svg
  81. 1
      odoo_mail_management/static/src/img/note_FILL0_wght400_GRAD0_opsz48.svg
  82. 1
      odoo_mail_management/static/src/img/outbox.svg
  83. BIN
      odoo_mail_management/static/src/img/pdf.png
  84. 1
      odoo_mail_management/static/src/img/refresh_black_24dp.svg
  85. 1
      odoo_mail_management/static/src/img/search_black_24dp.svg
  86. 1
      odoo_mail_management/static/src/img/star_black_24dp.svg
  87. 1
      odoo_mail_management/static/src/img/star_border_black_24dp.svg
  88. 1
      odoo_mail_management/static/src/img/unarchive_FILL1_wght400_GRAD0_opsz48.svg
  89. 1
      odoo_mail_management/static/src/img/yellow_star.svg
  90. 29
      odoo_mail_management/static/src/js/AttachmentMail.js
  91. 136
      odoo_mail_management/static/src/js/ComposeMail.js
  92. 83
      odoo_mail_management/static/src/js/MailBody.js
  93. 276
      odoo_mail_management/static/src/js/MailHome.js
  94. 41
      odoo_mail_management/static/src/js/MessageView.js
  95. 9
      odoo_mail_management/static/src/js/SentMail.js
  96. 16
      odoo_mail_management/static/src/xml/attachment_mail_templates.xml
  97. 75
      odoo_mail_management/static/src/xml/compose_mail_templates.xml
  98. 80
      odoo_mail_management/static/src/xml/mail_body_templates.xml
  99. 262
      odoo_mail_management/static/src/xml/mail_page_templates.xml
  100. 59
      odoo_mail_management/static/src/xml/message_viewer_templates.xml

46
odoo_mail_management/README.rst

@ -0,0 +1,46 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
Email Management in Odoo
========================
This Module will help to manage mails in odoo
Configuration
=============
* Configure outgoing mail server
License
-------
General Public License, Version 3 (AGPL v3).
(https://www.gnu.org/licenses/agpl-3.0-standalone.html)
Company
-------
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__
Credits
-------
* Developers: (V16) Hafeesul ALi, Jumana Jabin MP Contact: odoo@cybrosys.com
Contacts
--------
* Mail Contact : odoo@cybrosys.com
* Website : https://cybrosys.com
Bug Tracker
-----------
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported.
Maintainer
==========
.. image:: https://cybrosys.com/images/logo.png
:target: https://cybrosys.com
This module is maintained by Cybrosys Technologies.
For support and more information, please visit `Our Website <https://cybrosys.com/>`__
Further information
===================
HTML Description: `<static/description/index.html>`__

22
odoo_mail_management/__init__.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Hafeesul Ali(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# 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 (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import models

55
odoo_mail_management/__manifest__.py

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Hafeesul Ali(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# 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 (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
{
'name': 'Email Management in Odoo',
'version': '16.0.1.0.0',
'category': 'Productivity',
'summary': 'This Module will help to manage all type of mails in Odoo',
'description': """Email Management in Odoo is a comprehensive module that
enhances the email handling capabilities of Odoo.This module is designed
to streamline and improve the management of all types of emails, providing
a user-friendly interface and additional functionalities for increased
productivity.""",
'author': 'Cybrosys Techno Solutions',
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': 'https://www.cybrosys.com',
'depends': ['mail', 'calendar', 'note', 'base'],
'data': [
'security/ir.model.access.csv',
'data/mail_icon_data.xml',
'views/res_config_views.xml',
'views/odoo_mail_views.xml',
'views/mail_attachment_views.xml'
],
'assets': {
'web.assets_backend': [
"odoo_mail_management/static/src/css/main.css",
"odoo_mail_management/static/src/js/*",
"odoo_mail_management/static/src/xml/*",
]},
'images': ['static/description/banner.jpg'],
'license': 'AGPL-3',
'installable': True,
'application': False,
'auto_install': False,
}

10
odoo_mail_management/data/mail_icon_data.xml

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- This XML file is used to define a record in Odoo. It sets the default logo for the main company. -->
<data noupdate="1">
<record id="main_company" model="mail.icon">
<field name="mail_icon" model="mail.icon"
eval="obj()._get_default_logo(original=True)"/>
</record>
</data>
</odoo>

7
odoo_mail_management/doc/RELEASE_NOTES.md

@ -0,0 +1,7 @@
## Module <odoo_mail_management>
#### 06.07.2024
#### Version 16.0.1.0.0
#### ADD
- Initial commit for Odoo Mail Management

26
odoo_mail_management/models/__init__.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Hafeesul Ali(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# 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 (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import ir_attachment
from . import mail_attachment
from . import mail_icon
from . import mail_mail
from . import res_config_settings

46
odoo_mail_management/models/ir_attachment.py

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Hafeesul Ali(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# 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 (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, models
class IrAttachment(models.Model):
"""
This model extends the functionality of 'ir.attachment' in Odoo.
"""
_inherit = 'ir.attachment'
@api.model
def get_fields(self, value):
"""
Retrieve specified fields from attachments identified by the given list of IDs.
"""
data_list = []
for values in value:
attach = self.env['ir.attachment'].browse(values)
data_dict = {
'attachment': attach.id,
'datas': attach.datas,
'mimetype': attach.mimetype,
'name': attach.name
}
data_list.append(data_dict)
return data_list

34
odoo_mail_management/models/mail_attachment.py

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Hafeesul Ali(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# 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 (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class MailAttachment(models.TransientModel):
"""This model is used for handling mail attachments in Odoo."""
_name = "mail.attachment"
_description = "Mail Attachment"
mail_attachment = fields.Binary(string="Attachment",
help="Binary field to store the attachment"
" data.")
file_name = fields.Char(string="File Name",
help="Name of the attached file.")

69
odoo_mail_management/models/mail_icon.py

@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Hafeesul Ali(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# 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 (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
import base64
from odoo import api, fields, models, tools
from odoo.modules.module import get_resource_path
class MailIcon(models.Model):
"""This model is used to manage mail icons in Odoo."""
_name = "mail.icon"
_description = "Mail Icon "
def _get_default_logo(self, original=False):
"""Method to load default logo"""
img_path = get_resource_path('odoo_mail_management',
'static/src/img/logo.png')
with tools.file_open(img_path, 'rb') as f:
return base64.b64encode(f.read())
mail_icon = fields.Binary(string="Mail Icon",
help="Binary field to store the mail icon.",
default=_get_default_logo)
@api.model_create_multi
def create(self, vals_list):
"""Method to super create function and call _handle_icon() function"""
for vals in vals_list:
self._handle_icon(vals)
mail_settings = super().create(vals_list)
return mail_settings
def write(self, values):
"""Method to super write function and call _handle_icon() function"""
self._handle_icon(values)
mail_settings = super().create(values)
return mail_settings
@api.model
def _handle_icon(self, vals):
"""Method to handle the icon"""
if vals.get('mail_icon'):
vals['mail_icon'] = base64.b64encode(
tools.image_process(base64.b64decode(vals['mail_icon']),
size=(150, 150), crop='center'))
@api.model
def load_logo(self):
"""Method to load logo into mail view"""
return self.env['mail.icon'].search([], order="id desc", limit=1). \
mail_icon

190
odoo_mail_management/models/mail_mail.py

@ -0,0 +1,190 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Hafeesul Ali(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# 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 (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import api, fields, models
import re
from odoo.exceptions import ValidationError
class MailMail(models.Model):
"""This model extends the 'mail.mail' model in Odoo to add additional
features."""
_inherit = "mail.mail"
is_starred = fields.Boolean(string="Starred Mail", default=False,
help="Flag indicating whether the mail is"
" starred.")
active = fields.Boolean(default=True,
help="Flag indicating whether the mail is active.")
@api.model
def get_mail_count(self):
"""Method to get count of all mails,sent mails
,mails in outbox,starred mails and archived mails."""
all_count = self.sudo().search_count(
[('create_uid', '=', self.env.user.id)])
sent_count = self.sudo().search_count(
[('create_uid', '=', self.env.user.id), ('state', '=', 'sent')])
outbox_count = self.sudo().search_count(
[('state', '=', 'exception'),
('create_uid', '=', self.env.user.id)])
stared_count = self.sudo().search_count(
[('is_starred', '=', True), ('create_uid', '=', self.env.user.id)])
archived_count = self.sudo().search_count(
[('active', '=', False), ('create_uid', '=', self.env.user.id)])
mail_dict = {'all_count': all_count,
'sent_count': sent_count,
'outbox_count': outbox_count,
'starred_count': stared_count,
"archived_count": archived_count, }
return mail_dict
@api.model
def get_starred_mail(self):
"""Method to fetch all starred mails."""
mails = self.sudo().search(
[('is_starred', '=', True), ('create_uid', '=', self.env.user.id)])
return mails.read()
@api.model
def delete_mail(self, ids):
"""Method to unlink mail."""
mails = self.sudo().search(
[('id', 'in', ids), ('create_uid', '=', self.env.user.id), '|',
('active', '=', False), ('id', 'in', ids),
('create_uid', '=', self.env.user.id)])
for mail in mails:
mail.sudo().unlink()
@api.model
def open_mail(self, *args):
"""Method to open a mail and show its content."""
detail = self.sudo().search(
[('id', '=', *args), ('create_uid', '=', self.env.user.id), '|',
('active', '=', False), ('id', '=', *args),
('create_uid', '=', self.env.user.id)]).body_html
return detail
@api.model
def star_mail(self, *args):
"""Method to make a mail starred."""
self.search([('id', '=', *args),
('create_uid', '=', self.env.user.id)]). \
write({"is_starred": True})
@api.model
def unstar_mail(self, *args):
"""Method to make a mail not starred."""
self.sudo().search([('id', '=', *args),
('create_uid', '=', self.env.user.id)]). \
write({"is_starred": False})
@api.model
def archive_mail(self, *args):
"""Method to archive mail."""
self.sudo().search([('id', '=', *args),
('create_uid', '=', self.env.user.id)]). \
write({"active": False})
@api.model
def get_archived_mail(self):
"""Method to get archived mails"""
mail_dict = {}
mails = self.sudo().search([('active', '=', False),
('create_uid', '=', self.env.user.id)])
for record in mails:
if record.email_to:
mail_dict[str(record.mail_message_id)] = ({
"id": record.id,
"sender": record.email_to,
"subject": record.subject,
"date": fields.Date.to_date(record.create_date), })
elif record.recipient_ids:
mail_dict[str(record.mail_message_id)] = ({
"id": record.id,
"sender": record.recipient_ids.name,
"subject": record.subject,
"date": fields.Date.to_date(record.create_date), })
return mails.read()
@api.model
def unarchive_mail(self, *args):
"""Method to make mail unarchived."""
self.sudo().search([('active', '=', False), ('id', '=', *args),
('create_uid', '=', self.env.user.id)]). \
write({'active': True})
@api.model
def delete_checked_mail(self, *args):
"""Method to delete checked mails."""
self.search(
[('id', '=', *args), '|', ('id', '=', *args),
('active', '=', False)]).sudo().unlink()
@api.model
def archive_checked_mail(self, *args):
"""Method to archive checked mails."""
self.sudo().search([('id', 'in', *args),
('create_uid', '=', self.env.user.id)]). \
write({"active": False})
@api.model
def sent_mail(self, **kwargs):
"""Method to compose and send mail."""
attachment_ids = []
mail_from = self.env.user.email
subject = kwargs.get('subject')
recipient = kwargs.get('recipient')
if not re.match(r"[^@]+@gmail\.com", recipient):
raise ValidationError("Recipient email should be a Gmail address.")
content = kwargs.get('content')
content_html = content.replace('\n', '<br>')
image = kwargs.get('images')
if image:
for img_data in image:
image_data = img_data.get('image_uri')
if image_data:
attachment = self.env['ir.attachment'].create({
'name': img_data.get('name'),
'datas': image_data,
'res_model': 'mail.mail',
})
attachment_ids.append((4, attachment.id))
mail_id = self.sudo().with_user(user=self.env.user).create({
"subject": subject,
"email_to": recipient,
"email_from": mail_from,
"body_html": content_html,
"attachment_ids": attachment_ids
})
mail_id.send()
return mail_id.read()
@api.model
def retry_mail(self, *args):
"""Method to retry failed messages"""
mail = self.search([('id', '=', int(*args)),
('create_uid', '=', self.env.user.id)])
mail.mark_outgoing()
mail.send()

46
odoo_mail_management/models/res_config_settings.py

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Hafeesul Ali(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# 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 (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class ResConfigSettings(models.TransientModel):
"""This model extends the 'res.config.settings' model in Odoo to add
additional settings."""
_inherit = "res.config.settings"
def _default_mail_icon_id(self):
"""Method to return default mail_icon model """
return self.env['mail.icon'].search([], order='id desc', limit=1)
mail_icon_id = fields.Many2one("mail.icon",
default=_default_mail_icon_id,
ondelete='cascade',
string="Mail Icon Id",
help="Mail Icon Id")
icon = fields.Binary('mail_icon',
related='mail_icon_id.mail_icon',
readonly=False,
help="Icon")
custom_mail_logo = fields.Boolean(string="Custom Mail Logo",
help="Customize your mail logo",
config_parameter="odoo_mail_management."
"custom_mail_logo")

3
odoo_mail_management/security/ir.model.access.csv

@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_mail_attachment,access.mail.attachment,model_mail_attachment,base.group_user,1,1,1,1
access_mail_icon,access.mail.icon,model_mail_icon,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_mail_attachment access.mail.attachment model_mail_attachment base.group_user 1 1 1 1
3 access_mail_icon access.mail.icon model_mail_icon base.group_user 1 1 1 1

BIN
odoo_mail_management/static/description/assets/icons/check.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
odoo_mail_management/static/description/assets/icons/chevron.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
odoo_mail_management/static/description/assets/icons/cogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
odoo_mail_management/static/description/assets/icons/consultation.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
odoo_mail_management/static/description/assets/icons/ecom-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

BIN
odoo_mail_management/static/description/assets/icons/education-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

BIN
odoo_mail_management/static/description/assets/icons/hotel-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

BIN
odoo_mail_management/static/description/assets/icons/license.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
odoo_mail_management/static/description/assets/icons/lifebuoy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
odoo_mail_management/static/description/assets/icons/manufacturing-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
odoo_mail_management/static/description/assets/icons/pos-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

BIN
odoo_mail_management/static/description/assets/icons/puzzle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

BIN
odoo_mail_management/static/description/assets/icons/restaurant-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

BIN
odoo_mail_management/static/description/assets/icons/service-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
odoo_mail_management/static/description/assets/icons/trading-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
odoo_mail_management/static/description/assets/icons/training.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

BIN
odoo_mail_management/static/description/assets/icons/update.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
odoo_mail_management/static/description/assets/icons/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 988 B

BIN
odoo_mail_management/static/description/assets/icons/wrench.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
odoo_mail_management/static/description/assets/misc/categories.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
odoo_mail_management/static/description/assets/misc/check-box.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
odoo_mail_management/static/description/assets/misc/compass.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
odoo_mail_management/static/description/assets/misc/corporate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
odoo_mail_management/static/description/assets/misc/customer-support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
odoo_mail_management/static/description/assets/misc/cybrosys-logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
odoo_mail_management/static/description/assets/misc/features.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

BIN
odoo_mail_management/static/description/assets/misc/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
odoo_mail_management/static/description/assets/misc/pictures.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
odoo_mail_management/static/description/assets/misc/pie-chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
odoo_mail_management/static/description/assets/misc/right-arrow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

BIN
odoo_mail_management/static/description/assets/misc/star.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
odoo_mail_management/static/description/assets/misc/support.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
odoo_mail_management/static/description/assets/misc/whatsapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
odoo_mail_management/static/description/assets/modules/module01.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
odoo_mail_management/static/description/assets/modules/module02.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
odoo_mail_management/static/description/assets/modules/module03.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
odoo_mail_management/static/description/assets/modules/module04.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
odoo_mail_management/static/description/assets/modules/module05.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
odoo_mail_management/static/description/assets/modules/module06.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/12.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/13.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/14.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/8.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/9.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
odoo_mail_management/static/description/assets/screenshots/hero.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

BIN
odoo_mail_management/static/description/banner.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
odoo_mail_management/static/description/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

751
odoo_mail_management/static/description/index.html

@ -0,0 +1,751 @@
<div style="background-color: #714B67; height: 810px; width: 100%; padding: 15px; position: relative;">
<!-- TITLE BAR -->
<div class="d-flex align-items-center justify-content-between"
style="border-bottom: 1px solid #875A7B; padding: 15px; display: flex; justify-content: space-between; align-items: center;">
<img src="assets/misc/cybrosys-logo.png" width="42" height="42"
style="width: 42px; height: 42px;"/>
<div>
<div
style="color: #7C7BAD; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Community
</div>
<div
style="color: #875A7B; font-size: 14px; font-family: 'Montserrat', sans-serif; font-weight: bold; background-color: white; display: inline-block; padding: 3px 10px; border-radius: 50px;"
class="mr-2">
<i class="fa fa-check mr-1"></i>Enterprise
</div>
</div>
</div>
<!-- END OF TITLE BAR -->
<!-- APP HERO -->
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12"
>
<h1
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #FFFFFF !important; font-size: 3.5rem !important; text-align: center !important;">
Email Management in Odoo</h1>
<p
style="font-family: 'Montserrat', sans-serif !important; font-weight: 300 !important; color: #FFFFFF !important; font-size: 1.4rem !important; text-align: center !important;">
Odoo Mail Management
</p>
<img src="./assets/screenshots/hero.gif" class="img-responsive" width="100%" height="auto" />
</div>
</div>
</div>
</div>
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px; margin-top: 300px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/compass.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Explore This
Module</h2>
</div>
<div class="row my-4" style="font-family: 'Montserrat', sans-serif;">
<div class="col-sm-12 col-md-6 my-3">
<a href="#overview">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Overview</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">Learn
more about this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#features">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Features</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
features of this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
<div class="col-sm-12 col-md-6 my-3">
<a href="#screenshots">
<div class="d-flex justify-content-between align-items-center"
style="background-color: #f5f5f5; padding: 30px; width: 100%;">
<div>
<span style="color: #714B67; font-size: 24px; font-weight: 500; display: block;">Screenshots</span>
<span style="color: #714B67; font-size: 16px; font-weight: 400; color:#282F33; display: block;">View
screenshots for this
module</span>
</div>
<img src="assets/misc/right-arrow.png" width="36" height="36"/>
</div>
</a>
</div>
</div>
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"
id="overview">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pie-chart.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
Overview
</h2>
</div>
<div class="row"
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 py-4">
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important; line-height: 30px !important;">
This module helps to manage mails in Odoo.Here we can
compose,search,star,archive,delete mail.We can view the outgoing mail,sent
mail,archived mail ,starred mail in separate tabs.
</p>
</div>
</div>
<!-- END OF OVERVIEW SECTION -->
<!-- FEATURES SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"
id="configuration">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pie-chart.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif !important; font-weight: 600 !important; color: #714B67 !important; font-size: 1.5rem !important;">
Configuration
</h2>
</div>
<div class="col-mg-12 pl-3">
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important; line-height: 30px !important;">
Configure Outgoing Mail Server</p>
</div>
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"
id="features">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/features.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Features
</h2>
</div>
<div class="row"
style="font-family: 'Montserrat', sans-serif; font-weight: 400; font-size: 14px; line-height: 200%;">
<div class="col-sm-12 col-md-6">
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Community &amp; Enterprise Support</h4>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div class="d-flex align-items-center"
style="margin-top: 30px; margin-bottom: 30px">
<img src="assets/misc/check-box.png" class="mr-2"/>
<h4
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Manage mails in Odoo</h4>
</div>
</div>
</div>
<!-- END OF FEATURES SECTION -->
<!-- SCREENSHOTS SECTION -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;"
id="screenshots">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/pictures.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Screenshots
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div style="display: block; margin: 30px auto;"> <h4 class="my-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Manage mails in Odoo.</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
We can see all mails in Odoo.
</p>
<img src="assets/screenshots/1.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div style="display: block; margin: 30px auto;">
<h4 class="my-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Search bar.</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
We can search a mail easily using this search bar.
</p>
<img src="assets/screenshots/2.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div style="display: block; margin: 30px auto;">
<h4 class="mt-2"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Checkbox.</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Checkbox that can select all mail,multiple mail to delete and archive multiple
mail together.
</p>
<img src="assets/screenshots/3.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div style="display: block; margin: 30px auto;">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Make mails starred.</h4>
<img src="assets/screenshots/4.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div style="display: block; margin: 30px auto;">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Delete and archive mail.</h4>
<img src="assets/screenshots/5.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div style="display: block; margin: 30px auto;">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Calendar,Notes and Contacts button.</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
Calendar,Notes and Contacts button to redirect into respective modules.
</p>
<img src="assets/screenshots/6.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div style="display: block; margin: 30px auto;">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Compose a mail</h4>
<img src="assets/screenshots/7.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div style="display: block; margin: 30px auto;">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Compose mail window.</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
we can compose mail easily here and have an option to attach file,button to extend
compose mail window.
</p>
<img src="assets/screenshots/8.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div style="display: block; margin: 30px auto;">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Large window to compose mail.</h4>
<img src="assets/screenshots/9.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div style="display: block; margin: 30px auto;">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Minimize Feature for the mail.</h4>
<img src="assets/screenshots/10.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div style="display: block; margin: 30px auto;">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Sent mails.</h4>
<img src="assets/screenshots/12.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
<div style="display: block; margin: 30px auto;">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Can See the Starred mails, Archived mails and outbox mails individually .</h4>
<img src="assets/screenshots/13.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
</div>
<div style="display: block; margin: 30px auto;">
<h4 class="mt-3"
style="font-family: 'Roboto', sans-serif !important; font-weight: 600 !important; color: #282F33 !important; font-size: 1.3rem !important;">
Custom Mail Logo.</h4>
<p
style="font-family: 'Roboto', sans-serif !important; font-weight: 400 !important; color: #282F33 !important; font-size: 1rem !important;">
User can change the mail logo from settings
</p>
<img src="assets/screenshots/14.png" class="img-responsive img-thumbnail border" width="100%"
height="auto" />
</div>
</div>
<!-- END OF SCREENSHOTS SECTION -->
<!-- SUGGESTED PRODUCTS -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/categories.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Related
Products
</h2>
</div>
<div class="row">
<div class="col-sm-12">
<div id="demo1" class="row carousel slide"
data-ride="carousel">
<!-- The slideshow -->
<div class="carousel-inner" style="padding: 30px;">
<div class="carousel-item active" style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/direct_send_email_template/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;"
src="./assets/modules/module01.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/sale_order_line_multi_warehouse/"
target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;"
src="./assets/modules/module02.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/pos_sync_orders/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;"
src="./assets/modules/module03.png">
</div>
</a>
</div>
</div>
<div class="carousel-item active" style="min-height: 198.656px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/fleet_complete_report/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;"
src="./assets/modules/module04.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/gender_contact/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;"
src="./assets/modules/module05.png">
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float:left">
<a href="https://apps.odoo.com/apps/modules/16.0/service_charges_pos/" target="_blank">
<div style="border-radius:10px">
<img class="img img-responsive center-block" style="border-radius: 0px;"
src="./assets/modules/module06.png">
</div>
</a>
</div>
</div>
</div>
<a class="carousel-control-prev" href="#demo1" data-slide="prev"
style="width:35px; color:#000"> <span
class="carousel-control-prev-icon"><i
class="fa fa-chevron-left"
style="font-size:24px"></i></span>
</a> <a class="carousel-control-next" href="#demo1"
data-slide="next" style="width:35px; color:#000">
<span class="carousel-control-next-icon"><i
class="fa fa-chevron-right"
style="font-size:24px"></i></span>
</a>
</div>
</div>
</div>
<!-- END OF RELATED PRODUCTS -->
<!-- OUR SERVICES -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/star.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Our Services
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #1dd1a1 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/cogs.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Customization</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ff6b6b !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/wrench.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6462CD !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/lifebuoy.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Support</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #ffa801 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/user.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Hire
Odoo
Developer</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #54a0ff !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/puzzle.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Integration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #6d7680 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/update.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Migration</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #786fa6 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/consultation.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Consultancy</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #f8a5c2 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/training.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Implementation</h6>
</div>
<div class="col-lg-4 d-flex flex-column justify-content-center align-items-center my-4">
<div class="d-flex justify-content-center align-items-center mx-3 my-3"
style="background-color: #e6be26 !important; border-radius: 15px !important; height: 80px; width: 80px;">
<img src="assets/icons/license.png" class="img-responsive"
height="48px" width="48px">
</div>
<h6 class="text-center"
style="font-family: Montserrat, 'sans-serif' !important; font-weight: bold;">
Odoo
Licensing Consultancy</h6>
</div>
</div>
</div>
<!-- END OF OUR SERVICES -->
<!-- OUR INDUSTRIES -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/corporate.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Our
Industries
</h2>
</div>
<div class="container my-5">
<div class="row">
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/trading-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Trading
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easily procure
and
sell your products</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/pos-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
POS
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Easy
configuration
and convivial experience</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/education-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Education
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
A platform for
educational management</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/manufacturing-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Manufacturing
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Plan, track and
schedule your operations</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/ecom-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
E-commerce &amp; Website
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Mobile
friendly,
awe-inspiring product pages</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/service-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Service Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Keep track of
services and invoice</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/restaurant-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Restaurant
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
Run your bar or
restaurant methodically</p>
</div>
</div>
<div class="col-lg-3">
<div class="my-4 d-flex flex-column justify-content-center"
style="background-color: #f6f8f9 !important; border-radius: 0px; padding: 2rem !important; height: 250px !important;">
<img src="assets/icons/hotel-black.png"
class="img-responsive mb-3" height="48px" width="48px">
<h5 style="font-family: Montserrat, sans-serif !important; color: #000 !important; font-weight: bold;">
Hotel Management
</h5>
<p style="font-family: Montserrat, sans-serif !important; font-size: 0.9rem !important;">
An
all-inclusive
hotel management application</p>
</div>
</div>
</div>
</div>
<!-- END OF OUR INDUSTRIES -->
<!-- SUPPORT -->
<div class="d-flex align-items-center"
style="border-bottom: 2px solid #714B67; padding: 15px 0px;">
<div class="d-flex justify-content-center align-items-center mr-2"
style="background-color: #F5F5F5; border-radius: 0px; width: 40px; height: 40px;">
<img src="assets/misc/customer-support.png"/>
</div>
<h2 class="mt-2"
style="font-family: 'Montserrat', sans-serif; font-size: 24px; font-weight: bold;">
Support
</h2>
</div>
<div class="container mt-5">
<div class="row">
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4 d-flex justify-content-center align-items-center"
style="background-color: #714B67; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/support.png" height="48" width="48"
style="width: 42px; height: 42px;"/>
</div>
<div>
<h4>Need Help?</h4>
<p style="line-height: 100%;">Got questions or need help?
Get in touch.</p>
<a href="mailto:odoo@cybrosys.com">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">
odoo@cybrosys.com</p>
</a>
</div>
</div>
</div>
<div class="col-sm-12 col-md-6">
<div style="background-color: #F6F8F9; padding: 30px; display: flex; align-items: center;">
<div class="mr-4 d-flex justify-content-center align-items-center"
style="background-color: #2AC44D; display: inline-block; height: 70px; width: 70px; display: flex; align-items: center; justify-content: center;">
<img src="assets/misc/whatsapp.png" height="52" width="52"
style="width: 52px; height: 52px;"/>
</div>
<div>
<h4>WhatsApp</h4>
<p style="line-height: 100%;">Say hi to us on WhatsApp!</p>
<a href="https://api.whatsapp.com/send?phone=918606827707">
<p style="font-weight: 400; font-size: 28px; line-height: 80%; color: #714B67;">
+91 86068
27707</p>
</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 my-5 d-flex justify-content-center align-items-center">
<img src="assets/misc/logo.png" width="144" height="31"
style="width:144px; height: 31px; margin-top: 40px;"/>
</div>
</div>
</div>
<!-- END OF SUPPORT -->

1331
odoo_mail_management/static/src/css/main.css

File diff suppressed because it is too large

1
odoo_mail_management/static/src/img/archive_black_24dp.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z"/></svg>

After

Width:  |  Height:  |  Size: 389 B

1
odoo_mail_management/static/src/img/attachment.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 96 960 960" width="48"><path d="M298 796q-91.164 0-154.582-64.5Q80 667 80 576t62.5-155.5Q205 356 296 356h430q63.525 0 108.763 45.544Q880 447.089 880 511.044 880 575 834.763 620.5 789.525 666 726 666H331q-38.22 0-64.61-26.141t-26.39-64Q240 538 267.5 512t65.5-26h393v40H332q-21 0-36.5 14.325-15.5 14.324-15.5 35.5Q280 597 295 611.5q15 14.5 36 14.5h395q47.88 0 80.94-33.289 33.06-33.288 33.06-81.5Q840 463 806.94 429.5T726 396H294q-73 0-123.5 52.875T120 576q0 75 51.5 127.5T297 756h429v40H298Z"/></svg>

After

Width:  |  Height:  |  Size: 562 B

1
odoo_mail_management/static/src/img/calendar_month_FILL0_wght400_GRAD0_opsz48.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 96 960 960" width="48"><path d="M180 976q-24 0-42-18t-18-42V296q0-24 18-42t42-18h65v-60h65v60h340v-60h65v60h65q24 0 42 18t18 42v620q0 24-18 42t-42 18H180Zm0-60h600V486H180v430Zm0-490h600V296H180v130Zm0 0V296v130Zm300 230q-17 0-28.5-11.5T440 616q0-17 11.5-28.5T480 576q17 0 28.5 11.5T520 616q0 17-11.5 28.5T480 656Zm-160 0q-17 0-28.5-11.5T280 616q0-17 11.5-28.5T320 576q17 0 28.5 11.5T360 616q0 17-11.5 28.5T320 656Zm320 0q-17 0-28.5-11.5T600 616q0-17 11.5-28.5T640 576q17 0 28.5 11.5T680 616q0 17-11.5 28.5T640 656ZM480 816q-17 0-28.5-11.5T440 776q0-17 11.5-28.5T480 736q17 0 28.5 11.5T520 776q0 17-11.5 28.5T480 816Zm-160 0q-17 0-28.5-11.5T280 776q0-17 11.5-28.5T320 736q17 0 28.5 11.5T360 776q0 17-11.5 28.5T320 816Zm320 0q-17 0-28.5-11.5T600 776q0-17 11.5-28.5T640 736q17 0 28.5 11.5T680 776q0 17-11.5 28.5T640 816Z"/></svg>

After

Width:  |  Height:  |  Size: 890 B

1
odoo_mail_management/static/src/img/clear_black_24dp.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>

After

Width:  |  Height:  |  Size: 268 B

1
odoo_mail_management/static/src/img/contact_page_FILL0_wght400_GRAD0_opsz48.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 96 960 960" width="48"><path d="M480 656q33 0 56.5-23.5T560 576q0-33-23.5-56.5T480 496q-33 0-56.5 23.5T400 576q0 33 23.5 56.5T480 656ZM320 816h320v-23q0-24-13-44t-36-30q-26-11-53.5-17t-57.5-6q-30 0-57.5 6T369 719q-23 10-36 30t-13 44v23Zm420 160H220q-24 0-42-18t-18-42V236q0-24 18-42t42-18h341l239 239v501q0 24-18 42t-42 18Zm0-60V442L534 236H220v680h520Zm-520 0V236v680Z"/></svg>

After

Width:  |  Height:  |  Size: 441 B

1
odoo_mail_management/static/src/img/delete_black_24dp.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>

After

Width:  |  Height:  |  Size: 234 B

1
odoo_mail_management/static/src/img/edit_square_FILL0_wght400_GRAD0_opsz48.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 96 960 960" width="48"><path d="M180 1044q-24 0-42-18t-18-42V384q0-24 18-42t42-18h405l-60 60H180v600h600V636l60-60v408q0 24-18 42t-42 18H180Zm300-360Zm182-352 43 42-285 284v86h85l286-286 42 42-303 304H360V634l302-302Zm171 168L662 332l100-100q17-17 42.311-17T847 233l84 85q17 18 17 42.472T930 402l-97 98Z"/></svg>

After

Width:  |  Height:  |  Size: 375 B

1
odoo_mail_management/static/src/img/expand_icon.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M344 0H488c13.3 0 24 10.7 24 24V168c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-39-39-87 87c-9.4 9.4-24.6 9.4-33.9 0l-32-32c-9.4-9.4-9.4-24.6 0-33.9l87-87L327 41c-6.9-6.9-8.9-17.2-5.2-26.2S334.3 0 344 0zM168 512H24c-13.3 0-24-10.7-24-24V344c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2l39 39 87-87c9.4-9.4 24.6-9.4 33.9 0l32 32c9.4 9.4 9.4 24.6 0 33.9l-87 87 39 39c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8z"/></svg>

After

Width:  |  Height:  |  Size: 659 B

BIN
odoo_mail_management/static/src/img/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

1
odoo_mail_management/static/src/img/menu_black_24dp.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></svg>

After

Width:  |  Height:  |  Size: 204 B

1
odoo_mail_management/static/src/img/note_FILL0_wght400_GRAD0_opsz48.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 96 960 960" width="48"><path d="M220 976q-24 0-42-18t-18-42V236q0-24 18-42t42-18h361l219 219v521q0 24-18 42t-42 18H220Zm331-554V236H220v680h520V422H551ZM220 236v186-186 680-680Z"/></svg>

After

Width:  |  Height:  |  Size: 249 B

1
odoo_mail_management/static/src/img/outbox.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 96 960 960" width="48"><path d="M453 634V445l-79 79-43-43 152-152 152 152-43 43-79-79v189h-60ZM180 936q-24 0-42-18t-18-42V276q0-24 18-42t42-18h600q24 0 42 18t18 42v600q0 24-18 42t-42 18H180Zm300-173q41 0 74-23.5t56-59.5h170V276H180v404h170q23 36 56 59.5t74 23.5Z"/></svg>

After

Width:  |  Height:  |  Size: 334 B

BIN
odoo_mail_management/static/src/img/pdf.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

1
odoo_mail_management/static/src/img/refresh_black_24dp.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg>

After

Width:  |  Height:  |  Size: 359 B

1
odoo_mail_management/static/src/img/search_black_24dp.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>

After

Width:  |  Height:  |  Size: 393 B

1
odoo_mail_management/static/src/img/star_black_24dp.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M0 0h24v24H0z" fill="none"/><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></svg>

After

Width:  |  Height:  |  Size: 282 B

1
odoo_mail_management/static/src/img/star_border_black_24dp.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z"/></svg>

After

Width:  |  Height:  |  Size: 351 B

1
odoo_mail_management/static/src/img/unarchive_FILL1_wght400_GRAD0_opsz48.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 96 960 960" width="48"><path d="M180 936q-24 0-42-18t-18-42V353q0-15 3-25.5t11-19.5l56-76q8-9 18.5-12.5T233 216h494q14 0 24 3.5t18 12.5l57 76q8 9 11 19.5t3 25.5v523q0 24-18 42t-42 18H180Zm17-614h565l-36-46H233l-36 46Zm253 464h60V585l86 86 40-40-156-156-156 156 40 40 86-86v201Z"/></svg>

After

Width:  |  Height:  |  Size: 349 B

1
odoo_mail_management/static/src/img/yellow_star.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z"/></svg>

After

Width:  |  Height:  |  Size: 582 B

29
odoo_mail_management/static/src/js/AttachmentMail.js

@ -0,0 +1,29 @@
/** @odoo-module **/
import { Component, useRef} from "@odoo/owl";
import { _t } from "@web/core/l10n/translation";
import { Dialog } from "@web/core/dialog/dialog";
export class ImportDialog extends Component {
/**
*handle the json file and import the data
**/
setup() {
this.file = false
}
onChangeFileInput(ev) {
const { files } = ev.target
if (!files[0]) return;
this.file = files[0]
}
async onFileUpload(ev) { if (this.file){
this.props.addAttachment(this.file)
this.cancel()
}
}
cancel() {
this.props.close();
}
}
ImportDialog.template = "ImportDialog"
ImportDialog.components = { Dialog }

136
odoo_mail_management/static/src/js/ComposeMail.js

@ -0,0 +1,136 @@
/* @odoo-module*/
import {Component,useState,useRef} from '@odoo/owl'
import { useBus, useService } from "@web/core/utils/hooks";
import {ImportDialog} from "./AttachmentMail";
/**
* ComposeMail component for handling mail composition.
* @extends Component
*/
export class ComposeMail extends Component {
setup() {
this.orm = useService('orm')
this.root = useRef('root');
this.action = useService('action')
this.dialog = useService('dialog')
this.state = useState({
subject: "",
recipient: "",
content: "",
images: [],
originalHeight: null,
minimized: false,
attachedFiles: [],
})
this.contentState = useState({
images: [],
})
}
async imageReader(file) {
const fileReader = new FileReader();
fileReader.onload = (event) => {
const imageDataUrl = event.target.result; // Data URL of the image
if (imageDataUrl) {
this.state.images.push({name: file.name, image_uri: imageDataUrl.split(",")[1]})
}
};
fileReader.readAsDataURL(file);
}
contentHandler(file) {
switch (file.type) {
case "image/jpeg":
case "image/png":
case "image/gif":
case "image/svg+xml":
case "image/webp":
return this.imageReader(file);
case "application/pdf":
return this.imageReader(file);
case "text/csv":
return this.csvReader(file);
default:
console.warn(`Unsupported file type: ${file.type}`);
}
}
/**
* Method to send the composed mail.
*/
async sentMail() {
const {
subject,
recipient,
content,
images,
} = this.state
let sendMail = []
if (recipient) {
sendMail = await this.orm.call('mail.mail', 'sent_mail', [], {
subject,
recipient,
content,
images,
})
this.props.loadMail(...sendMail)
this.props.close()
window.location.reload()
}
}
/**
* Method to maximize or restore the mail composition window.
*/
maximizeMail() {
const mailBody = this.root.el;
const TextArea = this.root.el.querySelector("#content");
if (mailBody.classList.contains('maximized')) {
mailBody.style.height = '532px';
mailBody.style.right = '5%';
mailBody.style.width = '30%';
mailBody.style.position = 'fixed';
TextArea.style.height = '300px';
} else {
mailBody.style.height = '900px';
mailBody.style.right = '5%';
mailBody.style.width = '100%';
mailBody.style.position = 'absolute';
}
mailBody.classList.toggle('maximized');
}
/**
* Method to close the mail composition window.
*/
Close() {
this.props.close()
}
/**
* Method to minimize or restore the mail composition window.
*/
minimizeMail() {
const mailBody = this.root.el;
if (!this.state.minimized) {
this.state.originalHeight = mailBody.style.height;
mailBody.style.height = '50px';
} else {
mailBody.style.height = this.state.originalHeight;
}
this.state.minimized = !this.state.minimized;
}
/**
* Method to trigger the attachment action.
*/
async attachmentAction() {
this.dialog.add(ImportDialog, {
addAttachment: this.addAttachment.bind(this)
})
}
closeInput(index){
this.state.attachedFiles.splice(index, 1)
}
addAttachment(attachment) {
this.state.attachedFiles.push(attachment)
this.contentHandler(attachment)
}
}
ComposeMail.template = 'ComposeMail'

83
odoo_mail_management/static/src/js/MailBody.js

@ -0,0 +1,83 @@
/* @odoo-module*/
import { Component, useRef, useState ,markup} from '@odoo/owl'
import { useService } from "@web/core/utils/hooks";
/**
* MailBody component for displaying mail details.
* @extends Component
*/
export class MailBody extends Component {
setup() {
this.ref = useRef('root')
this.html_content = this.props.mail.body_html.replace(/<br>/g, '')
this.orm = useService('orm')
this.state = useState({
starred: false,
})
this.env.bus.addEventListener("SELECT:ALL", (event) => {
const { checked } = event.detail
this.ref.el.querySelector(".mail_check_box").checked = checked
this.props.onSelectMail(this.props.mail.id, checked)
})
}
/**
* Method triggered on click of the mail selection checkbox.
* @param {Object} ev - Event object.
*/
onClickSelect(ev) {
const checked = ev.target.checked
this.props.onSelectMail(this.props.mail.id, checked)
}
/**
* Method to archive the mail.
* @param {Object} event - Event object.
*/
async archiveMail(event){
var mail = this.props.mail.id
await this.orm.call('mail.mail','archive_mail',[mail])
}
/**
* Method to unarchive the mail.
* @param {Object} event - Event object.
*/
async unArchive(event){
var mail = this.props.mail.id
await this.orm.call('mail.mail','unarchive_mail',[mail])
}
/**
* Method to resend the mail.
* @param {Object} event - Event object.
*/
async resendMail(){
var mail = this.props.mail.id
await this.orm.call('mail.mail','retry_mail',[mail])
}
/**
* Method to delete the mail.
* @param {Object} event - Event object.
*/
async deleteMail(event){
var mail = this.props.mail.id
await this.orm.call('mail.mail','delete_checked_mail',[mail])
}
/**
* Method to star or unstar the mail.
* @param {Object} event - Event object.
*/
async starMail(event){
this.state.starred = !this.state.starred
var mail = this.props.mail.id
this.props.starMail(mail, this.state.starred)
await this.orm.call('mail.mail','star_mail',[mail])
}
/**
* Method to open the mail.
* @param {Object} event - Event object.
*/
async openMail(event){
var mail = this.props.mail
this.props.openMail(mail)
}
}
MailBody.template = 'MailBody'

276
odoo_mail_management/static/src/js/MailHome.js

@ -0,0 +1,276 @@
/* @odoo-module*/
import { registry } from '@web/core/registry';
import { Component , useRef , useState, onWillStart ,onMounted} from '@odoo/owl'
import { useService } from "@web/core/utils/hooks";
import { MailBody } from './MailBody'
import { SentMail } from './SentMail'
import { MessageView } from './MessageView'
import { ComposeMail } from './ComposeMail'
import { ImportDialog } from './AttachmentMail'
import { session } from "@web/session";
/**
* odooMail component for handling mail-related functionalities.
* @extends Component
*/
class odooMail extends Component {
setup() {
this.mailState = useState({
loadLogo: "",
loadMail: [],
getCount: "",
outBox: "",
mode: "tree",
formData: {},
mailType: "all"
})
this.dialogService = useService("dialog")
this.root = useRef('root');
this.action = useService('action')
this.orm = useService('orm')
this.selectedMails = []
onMounted(() => {
this.allMailView()
})
onWillStart(async ()=> {
this.mailState.loadLogo = await this.orm.call('mail.icon','load_logo',[])
// this.allMailView()
this.getCount()
})
}
/**
* Method to get the count of different mail categories.
*/
async getCount(){
this.mailState.getCount = await this.orm.call('mail.mail','get_mail_count',[])
}
/**
* Method to compose a new mail.
*/
async composeMail(){
this.dialogService.add(ComposeMail, {
loadMail: (mail) => {
this.mailState.loadMail.unshift(mail)
this.getCount()
}
})
}
/**
* Method triggered on click of the "Select All" checkbox.
* @param {Object} ev - Event object.
*/
onClickSelectAll(ev) {
const checked = ev.target.checked
this.env.bus.trigger("SELECT:ALL", { checked })
}
/**
* Getter method to get props for MailBody component.
* @returns {Object} - Props for MailBody component.
*/
get mailProps() {
return {
onSelectMail: this.onSelectMail.bind(this),
starMail: this.starMail.bind(this),
openMail: this.openMail.bind(this),
mailType: this.mailType,
}
}
/**
* Method to reset the mail view.
*/
resetView(){
this.mailState.formData = {}
this.mailState.mode = "tree"
}
/**
* Method to open a specific mail.
* @param {Object} mail - Mail object.
*/
openMail(mail) {
this.mailState.formData = mail
this.mailState.mode = "form"
}
/**
* Method to star or unstar a mail.
* @param {Number} mail - Mail ID.
* @param {Boolean} type - Type of action (star or unstar).
*/
starMail(mail, type){
if (type) {
this.mailState.getCount.starred_count ++
}
else this.mailState.getCount.starred_count --
}
/**
* Method triggered on selecting or deselecting a mail.
* @param {Number} mailId - Mail ID.
* @param {Boolean} check - Checked or not.
*/
onSelectMail(mailId, check) {
if (check) {
this.selectedMails.push(mailId)
}
else {
this.selectedMails.filter(item => item !== mailId)
}
}
/**
* Getter method to get the mail type.
* @returns {String} - Current mail type.
*/
get mailType() {
return this.mailState.mailType
}
/**
* Method to archive selected mails.
* @param {Object} event - Event object.
*/
async archiveMail(event){
if (this.selectedMails.length){
this.mailState.loadMail = this.mailState.loadMail.filter(item => !this.selectedMails.includes(item.id))
await this.orm.call('mail.mail','archive_mail',[this.selectedMails])
this.getCount()
this.selectedMails = []
}
}
/**
* Method to refresh the page.
* @param {Object} event - Event object.
*/
refreshPage(event){
window.location.reload()
}
/**
* Method to delete selected mails.
* @param {Object} event - Event object.
*/
async deleteMail(event){
if (this.selectedMails.length){
this.mailState.loadMail = this.mailState.loadMail.filter(item => !this.selectedMails.includes(item.id))
await this.orm.call('mail.mail','delete_mail',[this.selectedMails])
this.getCount()
this.selectedMails = []
}
}
/**
* Method to view all mails.
*/
async allMailView(){
await $(this.root.el.querySelector('.all_mail')).addClass('active');
$(this.root.el.querySelector('.archieved-mail')).removeClass('active');
$(this.root.el.querySelector('.sent-mail')).removeClass('active');
$(this.root.el.querySelector('.outbox')).removeClass('active');
$(this.root.el.querySelector('.sent')).removeClass('active');
this.mailState.mailType = 'all'
this.resetView()
this.mailState.loadMail = await this.orm.searchRead('mail.mail',[['create_uid', '=', session.uid]],[], { order: "create_date desc"})
}
/**
* Method to view starred mails.
*/
async starredMail(){
$(this.root.el.querySelector('.sent-mail')).addClass('active');
$(this.root.el.querySelector('.archieved-mail')).removeClass('active');
$(this.root.el.querySelector('.outbox')).removeClass('active');
$(this.root.el.querySelector('.sent')).removeClass('active');
$(this.root.el.querySelector('.all_mail')).removeClass('active');
this.mailState.mailType = "starred"
this.resetView()
this.mailState.loadMail = await this.orm.call('mail.mail','get_starred_mail',[])
}
/**
* Method to view archived mails.
*/
async archivedMail(){
$(this.root.el.querySelector('.archieved-mail')).addClass('active');
$(this.root.el.querySelector('.sent-mail')).removeClass('active');
$(this.root.el.querySelector('.outbox')).removeClass('active');
$(this.root.el.querySelector('.sent')).removeClass('active');
$(this.root.el.querySelector('.all_mail')).removeClass('active');
this.mailState.mailType = 'archive'
this.resetView()
this.mailState.loadMail = await this.orm.call('mail.mail','get_archived_mail',[])
}
/**
* Method to view outbox mails.
*/
async outboxMailView(){
$(this.root.el.querySelector('.outbox')).addClass('active');
$(this.root.el.querySelector('.archieved-mail')).removeClass('active');
$(this.root.el.querySelector('.sent-mail')).removeClass('active');
$(this.root.el.querySelector('.sent')).removeClass('active');
$(this.root.el.querySelector('.all_mail')).removeClass('active');
this.mailState.mailType = "outbox"
this.resetView()
this.mailState.loadMail = await this.orm.searchRead('mail.mail',[['create_uid', '=', session.uid],['state', '=', 'exception']],[], { order: "create_date desc"})
}
/**
* Method to view sent mails.
*/
async sentMail(){
$(this.root.el.querySelector('.sent')).addClass('active');
$(this.root.el.querySelector('.archieved-mail')).removeClass('active');
$(this.root.el.querySelector('.sent-mail')).removeClass('active');
$(this.root.el.querySelector('.outbox')).removeClass('active');
$(this.root.el.querySelector('.all_mail')).removeClass('active');
this.resetView()
this.mailState.loadMail = await this.orm.searchRead('mail.mail',[['create_uid', '=', session.uid],['state', '=', 'sent']],[], { order: "create_date desc"})
}
/**
* Method to redirect to the calendar view.
*/
redirectCalender(){
this.action.doAction({
name: "Calender",
type: 'ir.actions.act_window',
res_model: 'calendar.event',
view_mode: 'calendar,tree',
view_type: 'calendar',
views: [[false, 'calendar'], [false, 'tree']],
target: 'current',
});
}
/**
* Method to redirect to the notes view.
*/
redirectNote(){
this.action.doAction({
name: "Notes",
type: 'ir.actions.act_window',
res_model: 'note.note',
view_mode: 'kanban,form,tree,activity',
view_type: 'kanban',
views: [[false, 'kanban'], [false, 'form'], [false, 'tree'], [false, 'activity']],
target: 'current',
});
}
/**
* Method to redirect to the contacts view.
*/
redirectContacts(){
this.action.doAction({
name: "Contacts",
type: 'ir.actions.act_window',
res_model: 'res.partner',
view_mode: 'kanban,form,tree,activity',
view_type: 'kanban',
views: [[false, 'kanban'], [false, 'form'], [false, 'tree'], [false, 'activity']],
target: 'current',
});
}
/**
* Method to search mails based on user input.
*/
searchMail(){
var value= this.root.el.querySelector(".header-search-input").value.toLowerCase()
var inboxItems = this.root.el.querySelectorAll(".inbox-message-item");
inboxItems.forEach(item => {
var itemText = item.textContent.toLowerCase();
item.style.display = itemText.includes(value) ? "" : "none";
})
}
}
odooMail.template = 'OdooMail'
odooMail.components = {
MailBody, SentMail, ComposeMail,MessageView,ImportDialog
}
registry.category('actions').add('odoo_mail', odooMail);

41
odoo_mail_management/static/src/js/MessageView.js

@ -0,0 +1,41 @@
/* @odoo-module*/
import { Component } from '@odoo/owl';
import { useService } from "@web/core/utils/hooks";
import { useState, onMounted, markup, useRef} from "@odoo/owl";
/**
* MessageView component for displaying a message.
* @extends Component
*/
export class MessageView extends Component {
setup(){
this.root = useRef("root-mail")
this.action = useService("action");
this.html_content = markup(this.props.mail.body_html)
this.orm = useService("orm");
this.state = useState({
attachments: {},
data: [],
})
onMounted(this.fetch_data);
}
async fetch_data(){
var self = this
for (const ids in this.props.mail.attachment_ids) {
var value = this.props.mail.attachment_ids
await this.orm.call("ir.attachment", "get_fields", [value], {}).then((result) => {
self.state.attachments = result
});
}
}
onClickImage(value){
this.action.doAction({
type: "ir.actions.act_url",
url: "/web/content/" + value+ "?download=true",
});
}
}
MessageView.template = 'MessageView'

9
odoo_mail_management/static/src/js/SentMail.js

@ -0,0 +1,9 @@
/* @odoo-module*/
import { Component } from '@odoo/owl'
import { useBus, useService } from "@web/core/utils/hooks";
/**
* SentMail component for displaying sent mails.
* @extends Component
*/
export class SentMail extends Component {}
SentMail.template = 'SentMail'

16
odoo_mail_management/static/src/xml/attachment_mail_templates.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="ImportDialog" owl="1">
<Dialog size="'md'" title="'Attachments'">
<input type="file" name="file" id="file"
class="form-control" t-on-change="onChangeFileInput"
t-ref="root" required="1"/>
<t t-set-slot="footer">
<button class="btn btn-primary"
t-on-click="onFileUpload">Add </button>
<button class="btn" t-on-click="cancel"
>Cancel</button>
</t>
</Dialog>
</t>
</templates>

75
odoo_mail_management/static/src/xml/compose_mail_templates.xml

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- ComposeMail template for composing a new mail -->
<t t-name="ComposeMail" owl="1">
<div class="container" t-ref="root"
style="position: fixed; bottom: 3px; right: 5%; width: 30%; border: 1px solid #ccc; z-index: 1000; background: white;"
id="send_message" tabindex="-1"
aria-labelledby="send_message_label" aria-hidden="true"><br />
<div class="dialog ">
<form class="form_submit">
<div class="content-group">
<div class="header d-flex justify-content-between">
<h1 class="title fs-5" id="send_message_label">New Message</h1>
<div class="ms-auto">
<button class="btn" id="minimizeButton"
type="button"
style="margin-left: 297px; margin-top: -1px;"
t-on-click="minimizeMail">
<i class="fa fa-window-minimize"
aria-hidden="true"/>
</button>
<button class="btn" t-on-click="maximizeMail">
<img src="/odoo_mail_management/static/src/img/expand_icon.svg"
class="btn-icon btn-icon-sm"/>
</button>
<button type="button" class="btn-close"
aria-label="Close" t-on-click="Close"/>
</div>
</div>
<div class="body">
<input type="email" class="form-control"
id="Recipient" t-model="state.recipient"
aria-describedby="emailHelp" required="1"
placeholder="To"/>
<br/>
<input type="text" class="form-control"
id="subject" t-model="state.subject"
aria-describedby="emailHelp"
placeholder="Subject"/>
<br/>
<textarea class="dd form-control" id="content"
rows="5" t-model="state.content"
style="height:200px">
</textarea>
<br/>
<t t-foreach="state.attachedFiles" t-as="attachment" t-key="attachment_index">
<div class="custom-input"
style="width: max-content;min-width:240px;height: 23px;background-color: darkgrey;font: icon;display:flex;justify-content:space-between;align-items: center;padding:0.5rem;margin:0.5rem 0;">
<t t-out="attachment.name"/>
<button type="button" class="btn close-button" id="attachments"
style="margin-left: 10px;line-height:0px;"
t-on-click="() => this.closeInput(attachment_index)">✖</button>
</div>
</t>
</div>
<div class="footer d-flex justify-content-end">
<button type="submit"
style="border-radius: 15px; width: 85px;"
class="btn btn-primary"
t-on-click="sentMail">Send</button>
<div class="image-upload"
t-on-click="attachmentAction">
<label>
<img src="odoo_mail_management/static/src/img/attachment.svg"/>
</label>
</div>
</div>
</div>
</form>
</div>
</div>
</t>
</templates>

80
odoo_mail_management/static/src/xml/mail_body_templates.xml

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<!-- MailBody template for displaying individual mail items in the inbox -->
<t t-name="MailBody" owl="1">
<div class="inbox-message-item message-default-unread"
data-id="' + name.id + '" t-ref="root">
<div class="checkbox" style="margin-right: -12px;">
<button class="btn">
<input type="checkbox" id="checkbox"
data-id="' + name.id + '"
class="checkbox checkbox_func mail_check_box"
t-on-click="onClickSelect">
</input>
</button>
</div>
<div>
<button class="btn star" data-id="' + name.id + '" style="margin: 0;"
t-on-click="starMail">
<img t-if="!state.starred"
src="/odoo_mail_management/static/src/img/star_border_black_24dp.svg"
alt="Not starred" data-id="' + name.id + '"
class="btn-icon-sm btn-icon-alt btn-icon-hover message-btn-icon"
id="not_starred"/>
<img t-else=""
src="/odoo_mail_management/static/src/img/yellow_star.svg"
alt="Not starred"
class="btn-icon-sm btn-icon-alt btn-icon-hover message-btn-icon"
id="starred"/>
</button>
</div>
<div class="message-default" data-id="' + name.id + '"
t-on-click="openMail">
<div class="message-sender message-content">
<span t-out="props.mail.email_to"/>
</div>
<div class="message-subject message-content">
<span t-out="props.mail.description"/>
</div>
<div class="message-seperator message-content">-</div>
<div class="message-body message-content">
<span t-out="html_content"/>
</div>
<div class="gap message-content">&nbsp;</div>
<div class="message-date center-text">
<span style="margin-left: 500px;" t-out="props.mail.date"/>
</div>
</div>
<div class="message-group-hidden">
<div class="inbox-message-item-options">
<button class="btn">
<img t-if="props.mailType !== 'archive'"
src="/odoo_mail_management/static/src/img/archive_black_24dp.svg"
alt="Archive" data-id="' + name.id + '"
class="btn-icon-sm btn-icon-alt btn-icon-hover"
id="archive" t-on-click="archiveMail"/>
<img t-elif="props.mailType == 'archive'"
src="/odoo_mail_management/static/src/img/unarchive_FILL1_wght400_GRAD0_opsz48.svg"
alt="Archive" data-id="' + name.id + '"
class="btn-icon-sm btn-icon-alt btn-icon-hover"
id="archive" t-on-click="unArchive"/>
</button>
<button class="btn">
<img src="/odoo_mail_management/static/src/img/delete_black_24dp.svg"
alt="Delete" data-id="' + name.id + '"
class="btn-icon-sm btn-icon-alt btn-icon-hover"
id="delete" t-on-click="deleteMail"/>
</button>
<button class="btn">
<img t-if="props.mailType == 'outbox'"
src="/odoo_mail_management/static/src/img/refresh_black_24dp.svg"
alt="Retry"
class="btn-icon-sm btn-icon-alt btn-icon-hover"
id="retry"
t-on-click="resendMail"/>
</button>
</div>
</div>
</div>
</t>
</templates>

262
odoo_mail_management/static/src/xml/mail_page_templates.xml

@ -0,0 +1,262 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="tmp" xml:space="preserve">
<!-- OdooMail template for the main application -->
<t t-name="OdooMail" owl="1">
<div class="odoo_mails" t-ref="root">
<div class="body-wrapper">
<!-- HEADER -->
<header class="head">
<div class="header-group">
<img t-attf-src="data:image/png;base64,{{mailState.loadLogo}}"
style="width:25%"/>
</div>
<form class="header-search" action="">
<div class="icons">
<button id="js-header-search"
class="btn btn-nofill tooltip"
data-info="Search">
<img src="/odoo_mail_management/static/src/img/search_black_24dp.svg"
alt="Search"
class="btn-icon btn-icon-alt"/>
</button>
</div>
<input type="search" class="header-search-input"
placeholder="Search mail" t-on-input="searchMail"/>
</form>
</header>
<!-- LEFT SIDEBAR -->
<section class="left-sidebar">
<div class="left-sidebar-compose">
<button class="sidebar-btn-compose compose"
t-on-click="composeMail">
<img src="/odoo_mail_management/static/src/img/edit_square_FILL0_wght400_GRAD0_opsz48.svg"
alt="Compose a new email"
class="sidebar-btn-compose-icon"/>
<span class="sidebar-btn-compose-title">Compose</span>
</button>
</div>
<div class="left-siderbar-label">
<ul class="labels category-item-list">
<li class="category-item active all_mail"
id="all_mail" t-on-click="allMailView">
<div t-on-click="allMailView">
<svg class="category-item-icon"
xmlns="http://www.w3.org/2000/svg"
height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none"/>
<path
d="M19 3H4.99c-1.11 0-1.98.89-1.98 2L3 19c0 1.1.88 2 1.99 2H19c1.1 0 2-.9 2-2V5c0-1.11-.9-2-2-2zm0 12h-4c0 1.66-1.35 3-3 3s-3-1.34-3-3H4.99V5H19v10z"/>
</svg>
<span class="category-item-title "
t-on-click="allMailView">All mail
</span>
</div>
<span class="category-item-number all_count"
t-out="mailState.getCount.all_count"/>
</li>
<li class="category-item sent" id="sent"
t-on-click="sentMail">
<div>
<svg class="category-item-icon"
xmlns="http://www.w3.org/2000/svg"
height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
</svg>
<span class="category-item-title ">Sent</span>
</div>
<span class="category-item-number sent_count"
t-out="mailState.getCount.sent_count"/>
</li>
<li class="category-item sent-mail" id="starred_mails"
t-on-click="starredMail">
<div>
<svg class="category-item-icon"
xmlns="http://www.w3.org/2000/svg"
height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/>
</svg>
<span class="category-item-title">Starred
</span>
</div>
<span class="category-item-number starred_count"
t-out="mailState.getCount.starred_count"/>
</li>
<li class="category-item archieved-mail" id="archived_mails"
t-on-click="archivedMail">
<div>
<svg class="category-item-icon"
xmlns="http://www.w3.org/2000/svg"
height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z"/>
</svg>
<span class="category-item-title">Archived
</span>
</div>
<span class="category-item-number archived_count"
t-out="mailState.getCount.archived_count"/>
</li>
<li class="category-item outbox" id="outbox"
t-on-click="outboxMailView">
<div>
<svg class="category-item-icon"
xmlns="http://www.w3.org/2000/svg"
height="48"
viewBox="0 96 960 960" width="48">
<path d="M453 634V445l-79 79-43-43 152-152 152 152-43 43-79-79v189h-60ZM180 936q-24 0-42-18t-18-42V276q0-24 18-42t42-18h600q24 0 42 18t18 42v600q0 24-18 42t-42 18H180Zm300-173q41 0 74-23.5t56-59.5h170V276H180v404h170q23 36 56 59.5t74 23.5Z"/>
</svg>
<span class="category-item-title">Outbox</span>
</div>
<span class="category-item-number outbox_count"
t-out="mailState.getCount.outbox_count"/>
</li>
</ul>
</div>
</section>
<!-- BODY -->
<section class="inbox mail_inbox">
<!-- MAIL -->
<div class="inbox-menu">
<div class="inbox-menu-group">
<div class="inbox-btn-group">
<button class="btn-alt checkbox"
style="margin-top:6px;">
<input type="checkbox" id="checkall"
t-on-click="onClickSelectAll"/>
</button>
</div>
<button class="btn refresh" t-on-click="refreshPage">
<img src="/odoo_mail_management/static/src/img/refresh_black_24dp.svg"
alt="Refresh"
class="btn-icon btn-icon-sm btn-icon-alt btn-icon-hover"/>
</button>
<button class="btn delete_checked"
t-on-click="deleteMail">
<img src="/odoo_mail_management/static/src/img/delete_black_24dp.svg"
alt="Delete"
class="btn-icon-sm btn-icon-alt btn-icon-hover checkbox_delete"/>
</button>
<button class="btn archive_checked"
t-on-click="archiveMail">
<img src="/odoo_mail_management/static/src/img/archive_black_24dp.svg"
alt="archive"
class="btn-icon-sm btn-icon-alt btn-icon-hover checkbox_archive"/>
</button>
</div>
</div>
<div class="inbox-container">
<div class="inbox-category">
<div id="ctg-primary"
class="inbox-category-item active">
<svg class="inbox-category-icon btn-icon btn-icon-sm btn-icon-alt active"
xmlns="http://www.w3.org/2000/svg"
height="24px"
viewBox="0 0 24 24" width="24px"
fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none"/>
<path d="M19 3H4.99c-1.11 0-1.98.89-1.98 2L3 19c0 1.1.88 2 1.99 2H19c1.1 0 2-.9 2-2V5c0-1.11-.9-2-2-2zm0 12h-4c0 1.66-1.35 3-3 3s-3-1.34-3-3H4.99V5H19v10z"/>
</svg>
<span class="inbox-category-title">Primary</span>
</div>
</div>
<!-- MAIL CONTENT -->
<div class="content">
<t t-if="mailState.mode == 'tree'">
<MailBody t-foreach="mailState.loadMail"
t-as="mail" t-key="mail_index"
mail="mail" t-props="mailProps"/>
</t>
<t t-else="">
<MessageView mail="mailState.formData"/>
</t>
</div>
</div>
</section>
<!-- RIGHT SIDEBAR -->
<section class="app-container">
<div class="app-group">
<div class="app-item">
<button class="btn google_calender"
t-on-click="redirectCalender">
<img src="/odoo_mail_management/static/src/img/calendar_month_FILL0_wght400_GRAD0_opsz48.svg"
alt="Calendar"
class="btn-icon btn-icon-sm"/>
</button>
<p t-on-click="redirectCalender">Calendar</p>
</div>
<div class="app-item">
<button class="btn keep_note"
t-on-click="redirectNote">
<img src="/odoo_mail_management/static/src/img/note_FILL0_wght400_GRAD0_opsz48.svg"
alt="Keep"
class="btn-icon btn-icon-sm"/>
</button>
<p style="margin-left: 4px;" t-on-click="redirectNote">Notes</p>
</div>
<div class="app-item" style="margin-top: -13px;">
<button class=" btn contacts"
t-on-click="redirectContacts">
<img src="/odoo_mail_management/static/src/img/contact_page_FILL0_wght400_GRAD0_opsz48.svg"
alt="Contacts"
class="btn-icon btn-icon-sm"/>
</button>
<p t-on-click="redirectContacts">Contacts</p>
</div>
</div>
</section>
<!-- large modal-->
<div class="modal fade" id="large_modal" tabindex="-1"
aria-labelledby="send_message_label" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content large-modal">
<form class="large_form_submit">
<div class="modal-header">
<h1 class="modal-title fs-5"
id="send_message_label">New Message
</h1>
<button type="button" class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"/>
</div>
<div class="modal-body">
<input type="email" class="form-control"
id="l_Recipient"
aria-describedby="emailHelp"
required="1" placeholder="To"/>
<br/>
<input type="text" class="form-control"
id="l_subject"
aria-describedby="emailHelp"
placeholder="Subject"/>
<br/>
<textarea class="form-control" id="l_content"
rows="6"/>
</div>
<div class="modal-footer">
<button type="submit"
style="border-radius: 15px; width: 85px;"
class="btn btn-primary"
t-on-click="sentMail">Send
</button>
<div class="image-upload">
<label for="file-input">
<img src="/odoo_mail_management/static/src/img/attachment.svg"/>
</label>
<input id="file-input" type="file"/>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</t>
</templates>

59
odoo_mail_management/static/src/xml/message_viewer_templates.xml

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="tmp" xml:space="preserve">
<!-- MessageView template for displaying a single mail message -->
<t t-name="MessageView" owl="1">
<div class="message" t-ref="root-mail">
<h4 t-out="props.mail.description" style="margin-right: auto;"/>
<br/>
<div>
<strong>From:</strong>
<span t-out="props.mail.email_from"/>
</div>
<div>
<strong>To:</strong>
<span t-out="props.mail.email_to"/>
</div>
<br/>
<div>
<t t-out="html_content"/>
</div>
<div style="display: flex; gap: 1rem; flex-wrap: wrap; ">
<t t-foreach="this.state.attachments" t-as="data" t-key="data_index">
<div t-if="data.mimetype == 'image/jpeg' || data.mimetype == 'image/png' || data.mimetype == 'image/gif' || data.mimetype == 'image/svg+xml' || data.mimetype == 'image/webp'">
<div class="row">
<div class="img-container" style="">
<div class="hover-card" t-on-click="() => this.onClickImage(data.attachment)">
<i class="fa fa-download"/>
</div>
<img class="img-fluid" style="width: 300px;height: 100px" t-att-src="'data:image/png;base64,'+data.datas"
alt=""/>
</div>
</div>
</div>
<div t-if="data.mimetype == 'application/pdf'">
<div class="row bg-secondary">
<div class="d-flex flex-row">
<div>
<img class="p-2" style="width: 45px; height:45px"
src="/odoo_mail_management/static/src/img/pdf.png"
alt="PDF Preview"
/>
</div>
<div>
<p class="mt-3" t-out="data.name"/>
</div>
<div style="width: 50px"/>
<div>
<button type="download" class="btn mt-3"
t-on-click="() => this.onClickImage(data.attachment)">
<i class="text-black fa fa-download" aria-hidden="true"/>
</button>
</div>
</div>
</div>
</div>
</t>
</div>
</div>
</t>
</templates>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save