@ -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>`__ |
@ -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 |
@ -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, |
|||
} |
@ -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> |
@ -0,0 +1,7 @@ |
|||
## Module <odoo_mail_management> |
|||
|
|||
#### 06.07.2024 |
|||
#### Version 16.0.1.0.0 |
|||
#### ADD |
|||
|
|||
- Initial commit for Odoo Mail Management |
@ -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 |
@ -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 |
@ -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.") |
@ -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 |
@ -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() |
@ -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") |
|
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 589 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 967 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 61 KiB |
After Width: | Height: | Size: 116 KiB |
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 65 KiB |
After Width: | Height: | Size: 61 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 65 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 255 KiB |
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 17 KiB |
@ -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 & 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 & 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 --> |
After Width: | Height: | Size: 389 B |
After Width: | Height: | Size: 562 B |
After Width: | Height: | Size: 890 B |
After Width: | Height: | Size: 268 B |
After Width: | Height: | Size: 441 B |
After Width: | Height: | Size: 234 B |
After Width: | Height: | Size: 375 B |
After Width: | Height: | Size: 659 B |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 204 B |
After Width: | Height: | Size: 249 B |
After Width: | Height: | Size: 334 B |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 359 B |
After Width: | Height: | Size: 393 B |
After Width: | Height: | Size: 282 B |
After Width: | Height: | Size: 351 B |
After Width: | Height: | Size: 349 B |
After Width: | Height: | Size: 582 B |
@ -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 } |
@ -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' |
@ -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' |
@ -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); |
@ -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' |
@ -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' |
@ -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> |
@ -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> |
@ -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"> </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> |
@ -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> |
@ -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> |