@ -0,0 +1,48 @@ |
|||||
|
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg |
||||
|
:target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html |
||||
|
:alt: License: LGPL-3 |
||||
|
|
||||
|
Dynamic Hover on Related Fields |
||||
|
=============================== |
||||
|
Dynamic Hover on Related Fields Helps you to show the configured |
||||
|
fields in a tooltip popup |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
No additional configuration required |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
License |
||||
|
------- |
||||
|
General Public License, Version 3 (LGPL v3). |
||||
|
(https://www.gnu.org/licenses/lgpl-3.0-standalone.html) |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
* Developer: (V16) ASWIN A K, 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: ASWIN A K (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL 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: ASWIN A K (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
{ |
||||
|
'name': 'Dynamic Hover on Related Fields', |
||||
|
'version': '16.0.1.0.0', |
||||
|
'category': 'Extra Tools', |
||||
|
'summary': 'Dynamic Hover on Related Fields Helps you to ' |
||||
|
'show the configured fields in a tooltip popup', |
||||
|
'description': 'Enhance your user experience with ' |
||||
|
'Dynamic Hover on Related Fields! This feature allows ' |
||||
|
'you to effortlessly display configured fields in ' |
||||
|
'a convenient tooltip popup. You have the flexibility ' |
||||
|
'to choose which fields and models you want to showcase ' |
||||
|
'when hovering over relevant information. ' |
||||
|
'Simplify your interactions and access key data with ease.', |
||||
|
'author': 'Cybrosys Techno solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'maintainer': 'Cybrosys Techno Solutions', |
||||
|
'website': "https://www.cybrosys.com", |
||||
|
'depends': ['web'], |
||||
|
'data': [ |
||||
|
'security/ir.model.access.csv', |
||||
|
'views/hover_related_fields_views.xml' |
||||
|
], |
||||
|
'assets': { |
||||
|
'web.assets_backend': [ |
||||
|
'dynamic_hover_on_related_fields/static/src/xml/*.xml', |
||||
|
'dynamic_hover_on_related_fields/static/src/js/*.js', |
||||
|
], |
||||
|
}, |
||||
|
'images': ['static/description/banner.png'], |
||||
|
'license': 'LGPL-3', |
||||
|
'installable': True, |
||||
|
'application': True, |
||||
|
'auto_install': False, |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
## Module <dynamic_hover_on_related_fields> |
||||
|
|
||||
|
#### 20.04.2024 |
||||
|
#### Version 16.0.1.0.0 |
||||
|
#### ADD |
||||
|
- Initial Commit for Dynamic Hover on Related Fields |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: ASWIN A K (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from . import hover_related_fields |
@ -0,0 +1,120 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: ASWIN A K (odoo@cybrosys.com) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class HoverRelatedFields(models.Model): |
||||
|
""" |
||||
|
Model for managing hover-related fields and their configurations. |
||||
|
""" |
||||
|
_name = 'hover.related.fields' |
||||
|
_description = 'Hover Related Fields' |
||||
|
_rec_name = 'model_id' |
||||
|
_sql_constraints = [ |
||||
|
('unique_model_id', 'UNIQUE(model_id)', |
||||
|
'One model should only have one configuration.') |
||||
|
] |
||||
|
|
||||
|
model_ids = fields.Many2many( |
||||
|
'ir.model', |
||||
|
string='Models', |
||||
|
compute='_compute_model_ids', |
||||
|
help='Models related to the configuration ' |
||||
|
'for setting domain for model_id', |
||||
|
) |
||||
|
model_id = fields.Many2one( |
||||
|
'ir.model', |
||||
|
'Model', |
||||
|
domain="[('id', 'not in', model_ids)]", |
||||
|
help='Select a model for configuration', |
||||
|
) |
||||
|
field_ids = fields.Many2many( |
||||
|
'ir.model.fields', |
||||
|
string='Fields', domain="[('model_id', '=', model_id)]", |
||||
|
help='Fields related to the selected model', |
||||
|
) |
||||
|
active = fields.Boolean( |
||||
|
string='Active', |
||||
|
default=True, |
||||
|
help='Helps to archive the configurations') |
||||
|
|
||||
|
@api.depends('model_id') |
||||
|
def _compute_model_ids(self): |
||||
|
self.model_ids = self.search([]).mapped('model_id') |
||||
|
|
||||
|
@api.model |
||||
|
def finding_the_data_to_show_tooltip(self, info): |
||||
|
""" |
||||
|
Method to find data to display in tooltips based on the provided |
||||
|
information. |
||||
|
|
||||
|
:param info: Information about the tooltip request. |
||||
|
:type info: dict |
||||
|
:return: Data to display in the tooltip. |
||||
|
:rtype: list or bool |
||||
|
""" |
||||
|
current_record = self.env[info['resModel']].browse(int(info['resId'])) |
||||
|
field_name = info['field']['name'] |
||||
|
configured_model = self.search( |
||||
|
[('model_id.model', '=', info['field']['relation'])]) |
||||
|
required_data = [[ |
||||
|
{ |
||||
|
'id': field.id, |
||||
|
'field': field.field_description, |
||||
|
'field_name': field.name, |
||||
|
'ttype': field.ttype, |
||||
|
'value': rec[ |
||||
|
field.name |
||||
|
].display_name if field.ttype == 'many2one' else rec[field.name] |
||||
|
} for field in configured_model.field_ids |
||||
|
] for rec in current_record[field_name]] |
||||
|
return required_data if required_data != [[]] else False |
||||
|
|
||||
|
@api.model |
||||
|
def finding_the_data_to_show_tooltip_many2many(self, info): |
||||
|
""" |
||||
|
Method to find data for tooltips in many2many, |
||||
|
many2one relationships. |
||||
|
|
||||
|
:param info: Information about the tooltip request. |
||||
|
:type info: dict |
||||
|
:return: Data to display in the tooltip. |
||||
|
:rtype: list or string |
||||
|
""" |
||||
|
rec_to_show = self.env[info['field']['relation']].browse( |
||||
|
int(info['related_record_id'])) |
||||
|
configured_model = self.search( |
||||
|
[('model_id.model', '=', info['field']['relation'])]) |
||||
|
required_data = [ |
||||
|
{ |
||||
|
'id': field.id, |
||||
|
'field': field.field_description, |
||||
|
'field_name': field.name, |
||||
|
'ttype': field.ttype, |
||||
|
'value': rec_to_show[ |
||||
|
field.name |
||||
|
].display_name if field.ttype == 'many2one' else rec_to_show[field.name] |
||||
|
} |
||||
|
for field in configured_model.field_ids] |
||||
|
if required_data == [] and info['viewMode'] == 'list': |
||||
|
required_data = rec_to_show.display_name |
||||
|
return required_data |
|
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: 80 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: 3.2 KiB |
After Width: | Height: | Size: 589 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 565 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 967 B |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 73 KiB |
After Width: | Height: | Size: 319 KiB |
After Width: | Height: | Size: 146 KiB |
After Width: | Height: | Size: 149 KiB |
After Width: | Height: | Size: 148 KiB |
After Width: | Height: | Size: 216 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 14 KiB |
@ -0,0 +1,620 @@ |
|||||
|
<!----------------------------------------------------------------------------------> |
||||
|
<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: #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>Enterprise |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- END OF TITLE BAR --> |
||||
|
<div class="container"> |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-12 col-md-12 col-lg-12"> |
||||
|
<!-- APP HERO --> |
||||
|
<h1 style="color: #FFFFFF; font-weight: bolder; font-size: 50px; text-align: center; margin-top: 50px;"> |
||||
|
Dynamic Hover on Related Fields |
||||
|
</h1> |
||||
|
<p style="color:#FFFFFF; padding: 8px 15px; text-align: center; font-size: 24px;"> |
||||
|
Dynamic Hover on Related Fields Helps you to show the configured fields in a tooltip popup</p> |
||||
|
<!-- END OF APP HERO --> |
||||
|
<img src="assets/screenshots/hero-v16.gif" class="img-responsive" |
||||
|
style="width: 100%; margin-left: auto; margin-right: auto;"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- NAVIGATION SECTION --> |
||||
|
<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> |
||||
|
<!-- END OF NAVIGATION SECTION --> |
||||
|
|
||||
|
<!-- OVERVIEW SECTION --> |
||||
|
<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; font-size: 24px; font-weight: bold;"> |
||||
|
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"> |
||||
|
Enhance your user experience with Dynamic Hover on Related Fields! This feature enables you to effortlessly display configured fields in a convenient tooltip popup. With the flexibility to choose which fields and models you want to showcase when hovering over relevant information, you can simplify your interactions and access key data with ease. Whether it's navigating through complex datasets or swiftly retrieving important information, Dynamic Hover empowers you to streamline your workflow and enhance productivity. |
||||
|
</div> |
||||
|
<hr/> |
||||
|
</div> |
||||
|
<!-- END OF OVERVIEW SECTION --> |
||||
|
|
||||
|
<!-- FEATURES SECTION --> |
||||
|
<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"/> |
||||
|
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Dynamic Hover on Related Fields</span> |
||||
|
</div> |
||||
|
<div class="d-flex align-items-center" |
||||
|
style="margin-top: 30px; margin-bottom: 30px"> |
||||
|
<img src="assets/misc/check-box.png" class="mr-2"/> |
||||
|
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Customizable Field Selection</span> |
||||
|
</div> |
||||
|
<div class="d-flex align-items-center" |
||||
|
style="margin-top: 30px; margin-bottom: 30px"> |
||||
|
<img src="assets/misc/check-box.png" class="mr-2"/> |
||||
|
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Flexibility in Field and Model Selection</span> |
||||
|
</div> |
||||
|
<div class="d-flex align-items-center" |
||||
|
style="margin-top: 30px; margin-bottom: 30px"> |
||||
|
<img src="assets/misc/check-box.png" class="mr-2"/> |
||||
|
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Seamless Interaction</span> |
||||
|
</div> |
||||
|
<div class="d-flex align-items-center" |
||||
|
style="margin-top: 30px; margin-bottom: 30px"> |
||||
|
<img src="assets/misc/check-box.png" class="mr-2"/> |
||||
|
<span style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;">Enhanced Accessibility.</span> |
||||
|
</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;"> |
||||
|
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
||||
|
Configuration: Go to Dynamic Hover -> New -> We can see the fields model and fields to configure. |
||||
|
</h3> |
||||
|
<img src="assets/screenshots/dynamic1.png" class="img-thumbnail"> |
||||
|
</div> |
||||
|
<div style="display: block; margin: 30px auto;"> |
||||
|
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
||||
|
Configured Records: Go to Dynamic Hover -> We can see the configured models and fields. |
||||
|
</h3> |
||||
|
<img src="assets/screenshots/dynamic2.png" class="img-thumbnail"> |
||||
|
</div> |
||||
|
|
||||
|
<div style="display: block; margin: 30px auto;"> |
||||
|
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
||||
|
In Tree View: Hover over any configured related field to instantly view its data in popup |
||||
|
</h3> |
||||
|
<img src="assets/screenshots/dynamic3.png" class="img-thumbnail"> |
||||
|
</div> |
||||
|
|
||||
|
<div style="display: block; margin: 30px auto;"> |
||||
|
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
||||
|
In Form View </h3> |
||||
|
<img src="assets/screenshots/dynamic4.png" class="img-thumbnail"> |
||||
|
</div> |
||||
|
|
||||
|
<div style="display: block; margin: 30px auto;"> |
||||
|
<img src="assets/screenshots/dynamic5.png" class="img-thumbnail"> |
||||
|
</div> |
||||
|
|
||||
|
<div style="display: block; margin: 30px auto;"> |
||||
|
<h3 style="font-family: 'Montserrat', sans-serif; font-size: 18px; font-weight: bold;"> |
||||
|
In Many2many Tags |
||||
|
</h3> |
||||
|
<img src="assets/screenshots/dynamic6.png" class="img-thumbnail"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- END OF SCREENSHOTS SECTION --> |
||||
|
|
||||
|
<!-- RELATED 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" 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/dynamic_accounts_report/" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/1.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/product_brand_purchase/" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/2.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_product_image/" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/3.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/odoo_sale_order_line_views/#" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/4.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/base_accounting_kit/#" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/5.gif"> |
||||
|
</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/hr_payroll_community/" target="_blank"> |
||||
|
<div style="border-radius:10px"> |
||||
|
<img class="img img-responsive center-block" style="border-radius: 0px;" src="assets/modules/6.png"> |
||||
|
</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- Left and right controls --> |
||||
|
<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 --> |
@ -0,0 +1,31 @@ |
|||||
|
/** @odoo-module **/ |
||||
|
|
||||
|
export function getTooltipInfo(params) { |
||||
|
let widgetDescription = undefined; |
||||
|
if (params.fieldInfo.widget) { |
||||
|
widgetDescription = params.fieldInfo.FieldComponent.displayName; |
||||
|
} |
||||
|
|
||||
|
const info = { |
||||
|
viewMode: params.viewMode, |
||||
|
resModel: params.resModel, |
||||
|
resId: params.resId, |
||||
|
debug: Boolean(odoo.debug), |
||||
|
field: { |
||||
|
label: params.field.string, |
||||
|
name: params.field.name, |
||||
|
help: params.fieldInfo.help !== null ? params.fieldInfo.help : params.field.help, |
||||
|
type: params.field.type, |
||||
|
widget: params.fieldInfo.widget, |
||||
|
widgetDescription, |
||||
|
context: params.fieldInfo.context, |
||||
|
domain: params.field.domain, |
||||
|
modifiers: JSON.stringify(params.fieldInfo.modifiers), |
||||
|
changeDefault: params.field.change_default, |
||||
|
relation: params.field.relation, |
||||
|
selection: params.field.selection, |
||||
|
default: params.field.default, |
||||
|
}, |
||||
|
}; |
||||
|
return JSON.stringify(info); |
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
/** @odoo-module **/ |
||||
|
|
||||
|
import { FormLabel } from "@web/views/form/form_label" |
||||
|
import { patch } from "@web/core/utils/patch" |
||||
|
import { getTooltipInfo } from "./fieldToltip" |
||||
|
|
||||
|
patch(FormLabel.prototype, "Form_label", { |
||||
|
|
||||
|
/** |
||||
|
* Retrieves tooltip information for the FormLabel. |
||||
|
* @returns {string} JSON string representing tooltip information. |
||||
|
*/ |
||||
|
get tooltipInfo() { |
||||
|
if (!odoo.debug) { |
||||
|
return JSON.stringify({ |
||||
|
field: { |
||||
|
help: this.tooltipHelp, |
||||
|
}, |
||||
|
}); |
||||
|
} |
||||
|
return getTooltipInfo({ |
||||
|
viewMode: "form", |
||||
|
resModel: this.props.record.resModel, |
||||
|
resId: this.props.record.resId, |
||||
|
field: this.props.record.fields[this.props.fieldName], |
||||
|
fieldInfo: this.props.fieldInfo, |
||||
|
help: this.tooltipHelp, |
||||
|
}); |
||||
|
}, |
||||
|
}) |
@ -0,0 +1,41 @@ |
|||||
|
/** @odoo-module **/ |
||||
|
|
||||
|
import { patch } from "@web/core/utils/patch" |
||||
|
import { ListRenderer } from "@web/views/list/list_renderer"; |
||||
|
|
||||
|
patch(ListRenderer.prototype, "ListRenderer_patch", { |
||||
|
/** |
||||
|
* Generate tooltip information for a field. |
||||
|
* @param {Object} record - The record object. |
||||
|
* @param {Object} fields - The fields object. |
||||
|
* @returns {string} - JSON string containing tooltip information. |
||||
|
*/ |
||||
|
tolTipInfo(record, fields) { |
||||
|
const field = record.fields[fields.name] |
||||
|
const info = { |
||||
|
viewMode: "list", |
||||
|
resModel: record.resModel, |
||||
|
related_record_id: record.data[fields.name][0], |
||||
|
resId: record.resId, |
||||
|
debug: Boolean(odoo.debug), |
||||
|
field: { |
||||
|
name: field.name, |
||||
|
help: field?.help, |
||||
|
type: field.type, |
||||
|
domain: field.domain, |
||||
|
relation: field.relation, |
||||
|
}, |
||||
|
}; |
||||
|
return JSON.stringify(info); |
||||
|
}, |
||||
|
/** |
||||
|
* Check if the field type is many2one. |
||||
|
* @param {Object} record - The record object. |
||||
|
* @param {Object} fields - The fields object. |
||||
|
* @returns {boolean} - True if the field type is many2one, false otherwise. |
||||
|
*/ |
||||
|
isMany2one(record, fields){ |
||||
|
const field = record.fields[fields.name] |
||||
|
return field.type === 'many2one'; |
||||
|
} |
||||
|
}) |
@ -0,0 +1,39 @@ |
|||||
|
/** @odoo-module **/ |
||||
|
|
||||
|
import { patch } from "@web/core/utils/patch"; |
||||
|
import { Many2ManyTagsField } from "@web/views/fields/many2many_tags/many2many_tags_field"; |
||||
|
|
||||
|
patch(Many2ManyTagsField.prototype, "Many2ManyTagsField_patch", { |
||||
|
|
||||
|
/** |
||||
|
* Retrieves tag properties for the Many2ManyTagsField. |
||||
|
* @param {Object} record - The record for which tag properties are retrieved. |
||||
|
* @returns {Object} Tag properties object. |
||||
|
*/ |
||||
|
getTagProps(record) { |
||||
|
const field = this.props.record.fields[this.props.name] |
||||
|
const info = { |
||||
|
viewMode: "form", |
||||
|
resModel:this.props.record.resModel, |
||||
|
resId: this.props.record.resId, |
||||
|
related_record_id: record.resId, |
||||
|
debug: Boolean(odoo.debug), |
||||
|
field: { |
||||
|
name: field.name, |
||||
|
help: field?.help, |
||||
|
type: field.type, |
||||
|
domain: field.domain, |
||||
|
relation: field.relation, |
||||
|
}, |
||||
|
}; |
||||
|
return { |
||||
|
id: record.id, // datapoint_X
|
||||
|
resId: record.resId, |
||||
|
text: record.data.display_name, |
||||
|
colorIndex: record.data[this.props.colorField], |
||||
|
onDelete: !this.props.readonly ? () => this.deleteTag(record.id) : undefined, |
||||
|
onKeydown: this.onTagKeydown.bind(this), |
||||
|
info: JSON.stringify(info) |
||||
|
}; |
||||
|
} |
||||
|
}) |
@ -0,0 +1,49 @@ |
|||||
|
/** @odoo-module **/ |
||||
|
|
||||
|
import { patch } from "@web/core/utils/patch"; |
||||
|
import { Many2OneField } from "@web/views/fields/many2one/many2one_field"; |
||||
|
|
||||
|
patch(Many2OneField.prototype, "Many2OneField_patch", { |
||||
|
/** |
||||
|
* Generates tooltip information for the Many2OneField. |
||||
|
* @returns {string} JSON string representing tooltip information. |
||||
|
*/ |
||||
|
get tooltipInfo() { |
||||
|
return this.getTooltipInfo({ |
||||
|
viewMode: "form", |
||||
|
resModel: this.props.record.resModel, |
||||
|
related_record_id: this.props.record.data[this.props.name][0], |
||||
|
resId: this.props.record.resId, |
||||
|
field: this.props.record.fields[this.props.name], |
||||
|
fieldInfo: this.props.fieldInfo, |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Constructs tooltip information object based on provided parameters. |
||||
|
* @param {Object} params - Parameters for tooltip information. |
||||
|
* @param {string} params.viewMode - View mode of the record. |
||||
|
* @param {string} params.resModel - Model of the record. |
||||
|
* @param {number} params.resId - ID of the record. |
||||
|
* @param {Object} params.field - Field information. |
||||
|
* @param {Object} params.fieldInfo - Field information. |
||||
|
* @returns {string} JSON string representing tooltip information. |
||||
|
*/ |
||||
|
getTooltipInfo(params){ |
||||
|
const info = { |
||||
|
viewMode: params.viewMode, |
||||
|
resModel: params.resModel, |
||||
|
related_record_id: params.related_record_id, |
||||
|
resId: params.resId, |
||||
|
debug: Boolean(odoo.debug), |
||||
|
field: { |
||||
|
name: params.field.name, |
||||
|
help: params.field?.help, |
||||
|
type: params.field.type, |
||||
|
domain: params.field.domain, |
||||
|
relation: params.field.relation, |
||||
|
}, |
||||
|
}; |
||||
|
return JSON.stringify(info); |
||||
|
}, |
||||
|
}) |
@ -0,0 +1,204 @@ |
|||||
|
/** @odoo-module **/ |
||||
|
import { tooltipService } from "@web/core/tooltip/tooltip_service"; |
||||
|
import { browser } from "@web/core/browser/browser"; |
||||
|
import { registry } from "@web/core/registry"; |
||||
|
import { Tooltip } from "@web/core/tooltip/tooltip"; |
||||
|
import { hasTouch } from "@web/core/browser/feature_detection"; |
||||
|
const rpc = require('web.rpc') |
||||
|
import { whenReady } from "@odoo/owl"; |
||||
|
|
||||
|
const OPEN_DELAY = 400; |
||||
|
const CLOSE_DELAY = 200; |
||||
|
tooltipService.start = (env, { popover }) => { |
||||
|
let openTooltipTimeout; |
||||
|
let closeTooltip; |
||||
|
let target = null; |
||||
|
let touchPressed; |
||||
|
const elementsWithTooltips = new Map(); |
||||
|
|
||||
|
/** |
||||
|
* Closes the currently opened tooltip if any, or prevent it from opening. |
||||
|
*/ |
||||
|
function cleanup() { |
||||
|
browser.clearTimeout(openTooltipTimeout); |
||||
|
if (closeTooltip) { |
||||
|
closeTooltip(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks that the target is in the DOM and we're hovering the target. |
||||
|
* @returns {boolean} |
||||
|
*/ |
||||
|
function shouldCleanup() { |
||||
|
if (!target) { |
||||
|
return false; |
||||
|
} |
||||
|
if (!document.body.contains(target)) { |
||||
|
return true; // target is no longer in the DOM
|
||||
|
} |
||||
|
if (hasTouch()) { |
||||
|
return !touchPressed; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
async function getDataFromBackend(info) { |
||||
|
if (!info?.field?.relation ) return |
||||
|
if (info?.related_record_id){ |
||||
|
const requiredData = await rpc.query({ |
||||
|
model: "hover.related.fields", |
||||
|
method: "finding_the_data_to_show_tooltip_many2many", |
||||
|
args:[info]}); |
||||
|
info.requiredData = requiredData; |
||||
|
}else if(info?.resId){ |
||||
|
const requiredData = await rpc.query({ |
||||
|
model: "hover.related.fields", |
||||
|
method: "finding_the_data_to_show_tooltip", |
||||
|
args: [info]}); |
||||
|
info.requiredData = requiredData; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks whether there is a tooltip registered on the event target, and |
||||
|
* if there is, creates a timeout to open the corresponding tooltip |
||||
|
* after a delay. |
||||
|
* |
||||
|
* @param {HTMLElement} el the element on which to add the tooltip |
||||
|
* @param {object} param1 |
||||
|
* @param {string} [param1.tooltip] the string to add as a tooltip, if |
||||
|
* no tooltip template is specified |
||||
|
* @param {string} [param1.template] the name of the template to use for |
||||
|
* tooltip, if any |
||||
|
* @param {object} [param1.info] info for the tooltip template |
||||
|
* @param {'top'|'bottom'|'left'|'right'} param1.position |
||||
|
* @param {number} [param1.delay] delay after which the popover should |
||||
|
* open |
||||
|
*/ |
||||
|
async function openTooltip(el, { tooltip = "", template, info, position, delay = OPEN_DELAY }) { |
||||
|
await getDataFromBackend(info) |
||||
|
target = el; |
||||
|
cleanup(); |
||||
|
if (!tooltip && !template) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
openTooltipTimeout = browser.setTimeout(() => { |
||||
|
// verify that the element is still in the DOM
|
||||
|
if (target.isConnected) { |
||||
|
closeTooltip = popover.add( |
||||
|
target, |
||||
|
Tooltip, |
||||
|
{ tooltip, template, info }, |
||||
|
{ position } |
||||
|
); |
||||
|
// Prevent title from showing on a parent at the same time
|
||||
|
target.title = ""; |
||||
|
} |
||||
|
}, delay); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks whether there is a tooltip registered on the element, and |
||||
|
* if there is, creates a timeout to open the corresponding tooltip |
||||
|
* after a delay. |
||||
|
* |
||||
|
* @param {HTMLElement} el |
||||
|
*/ |
||||
|
function openElementsTooltip(el) { |
||||
|
if (elementsWithTooltips.has(el)) { |
||||
|
openTooltip(el, elementsWithTooltips.get(el)); |
||||
|
} else if (el.matches("[data-tooltip], [data-tooltip-template]")) { |
||||
|
const dataset = el.dataset; |
||||
|
const params = { |
||||
|
tooltip: dataset.tooltip, |
||||
|
template: dataset.tooltipTemplate, |
||||
|
position: dataset.tooltipPosition, |
||||
|
}; |
||||
|
if (dataset.tooltipInfo) { |
||||
|
params.info = JSON.parse(dataset.tooltipInfo); |
||||
|
} |
||||
|
if (dataset.tooltipDelay) { |
||||
|
params.delay = parseInt(dataset.tooltipDelay, 10); |
||||
|
} |
||||
|
openTooltip(el, params); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks whether there is a tooltip registered on the event target, and |
||||
|
* if there is, creates a timeout to open the corresponding tooltip |
||||
|
* after a delay. |
||||
|
* |
||||
|
* @param {MouseEvent} ev a "mouseenter" event |
||||
|
*/ |
||||
|
function onMouseenter(ev) { |
||||
|
openElementsTooltip(ev.target); |
||||
|
} |
||||
|
|
||||
|
function onMouseleave(ev) { |
||||
|
if (target === ev.target) { |
||||
|
cleanup(); |
||||
|
} |
||||
|
} |
||||
|
/** |
||||
|
* Checks whether there is a tooltip registered on the event target, and |
||||
|
* if there is, creates a timeout to open the corresponding tooltip |
||||
|
* after a delay. |
||||
|
* |
||||
|
* @param {TouchEvent} ev a "touchstart" event |
||||
|
*/ |
||||
|
function onTouchStart(ev) { |
||||
|
touchPressed = true; |
||||
|
openElementsTooltip(ev.target); |
||||
|
} |
||||
|
|
||||
|
whenReady(() => { |
||||
|
// Regularly check that the target is still in the DOM and if not, close the tooltip
|
||||
|
browser.setInterval(() => { |
||||
|
if (shouldCleanup()) { |
||||
|
cleanup(); |
||||
|
} |
||||
|
}, CLOSE_DELAY); |
||||
|
|
||||
|
if (hasTouch()) { |
||||
|
document.body.addEventListener("touchstart", onTouchStart); |
||||
|
|
||||
|
document.body.addEventListener("touchend", (ev) => { |
||||
|
if (ev.target.matches("[data-tooltip], [data-tooltip-template]")) { |
||||
|
if (!ev.target.dataset.tooltipTouchTapToShow) { |
||||
|
touchPressed = false; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
document.body.addEventListener("touchcancel", (ev) => { |
||||
|
if (ev.target.matches("[data-tooltip], [data-tooltip-template]")) { |
||||
|
if (!ev.target.dataset.tooltipTouchTapToShow) { |
||||
|
touchPressed = false; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// Listen (using event delegation) to "mouseenter" events to open the tooltip if any
|
||||
|
document.body.addEventListener("mouseenter", onMouseenter, { capture: true }); |
||||
|
// Listen (using event delegation) to "mouseleave" events to close the tooltip if any
|
||||
|
document.body.addEventListener("mouseleave", onMouseleave, { capture: true }); |
||||
|
}); |
||||
|
|
||||
|
return { |
||||
|
add(el, params) { |
||||
|
elementsWithTooltips.set(el, params); |
||||
|
return () => { |
||||
|
elementsWithTooltips.delete(el); |
||||
|
if (target === el) { |
||||
|
cleanup(); |
||||
|
} |
||||
|
}; |
||||
|
}, |
||||
|
}; |
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates xml:space="preserve"> |
||||
|
<!-- Inherit and extend the web.ListRenderer.RecordRow template --> |
||||
|
<t t-inherit="web.ListRenderer.RecordRow" t-inherit-mode="extension"> |
||||
|
<!-- Modify the attributes of the <td> element that has the t-att-data-tooltip attribute --> |
||||
|
<td t-att-data-tooltip="!isInvisible ? getCellTitle(column, record) : false" |
||||
|
position="attributes"> |
||||
|
<!-- Add the data-tooltip-template attribute with the value 'dynamic_hover_on_related_fields.RelatedFieldTooltip' --> |
||||
|
<attribute name="data-tooltip-template">dynamic_hover_on_related_fields.RelatedFieldTooltip</attribute> |
||||
|
<!-- Add the t-att-data-tooltip-info attribute with a dynamic value based on isMany2one and tolTipInfo functions --> |
||||
|
<attribute name="t-att-data-tooltip-info">isMany2one(record, column)? tolTipInfo(record, column) : false</attribute> |
||||
|
<!-- Add the t-att-data-tooltip-touch-tap-to-show attribute with the value 'true' --> |
||||
|
<attribute name="t-att-data-tooltip-touch-tap-to-show">true</attribute> |
||||
|
</td> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,28 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates xml:space="preserve"> |
||||
|
<!-- Inherit and extend the web.Many2OneField template --> |
||||
|
<t t-inherit="web.Many2OneField" t-inherit-mode="extension" owl="1"> |
||||
|
<!-- Replace the content --> |
||||
|
<t t-if="!props.canOpen" position="replace"> |
||||
|
<t t-if="!props.canOpen"> |
||||
|
<span> |
||||
|
<!-- Display the main value with a tooltip --> |
||||
|
<span t-esc="displayName" |
||||
|
t-att="{'data-tooltip-template': 'dynamic_hover_on_related_fields.RelatedFieldTooltip', 'data-tooltip-info': tooltipInfo, 'data-tooltip-touch-tap-to-show': 'true'}"/> |
||||
|
<t t-foreach="extraLines" t-as="extraLine" t-key="extraLine_index"> |
||||
|
<br /> |
||||
|
<span t-esc="extraLine" /> |
||||
|
</t> |
||||
|
</span> |
||||
|
</t> |
||||
|
</t> |
||||
|
<!-- Add tooltip-related attributes to the editable field link --> |
||||
|
<a t-if="props.value" position="attributes"> |
||||
|
<attribute name="t-att">{'data-tooltip-template': 'dynamic_hover_on_related_fields.RelatedFieldTooltip', 'data-tooltip-info': tooltipInfo, 'data-tooltip-touch-tap-to-show': 'true'}</attribute> |
||||
|
</a> |
||||
|
<!-- Add tooltip-related attributes to the autocomplete selection section --> |
||||
|
<div class="o_field_many2one_selection" position="attributes"> |
||||
|
<attribute name="t-att">{'data-tooltip-template': 'dynamic_hover_on_related_fields.RelatedFieldTooltip', 'data-tooltip-info': tooltipInfo, 'data-tooltip-touch-tap-to-show': 'true'}</attribute> |
||||
|
</div> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,41 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates xml:space="preserve"> |
||||
|
<!-- Define the RelatedFieldTooltip template --> |
||||
|
<t t-name="dynamic_hover_on_related_fields.RelatedFieldTooltip" owl="1"> |
||||
|
<!-- If requiredData is an object with at least one element --> |
||||
|
<div t-if="requiredData and requiredData.length > 0 and typeof requiredData === 'object'" style="color: #111;"> |
||||
|
<h6 style="color: #111;">Field Data</h6> |
||||
|
<ul class="o-tooltip--technical"> |
||||
|
<!-- Iterate over each line in requiredData --> |
||||
|
<t t-foreach="requiredData" t-as="line" t-key="line_index"> |
||||
|
<!-- Handle binary data --> |
||||
|
<li t-if="line.ttype === 'binary'"> |
||||
|
<span class="o-tooltip--technical--title" t-esc="line.field"/><span>:</span> |
||||
|
<img t-attf-src="data:image/png;base64,#{line.value}" style="width:40px; padding:5px;" t-att-alt="line.field"/> |
||||
|
</li> |
||||
|
<!-- Handle HTML data --> |
||||
|
<li t-elif="line.ttype === 'html'"> |
||||
|
<span class="o-tooltip--technical--title" t-esc="line.field"/><span>:</span> |
||||
|
<br/> |
||||
|
<div style="background:#111;"> |
||||
|
<iframe t-att-srcdoc="line.value" style="width: auto;; height: auto;"></iframe> |
||||
|
</div> |
||||
|
</li> |
||||
|
<!-- Handle other data types --> |
||||
|
<li t-else=""> |
||||
|
<span class="o-tooltip--technical--title" t-esc="line.field"/><span>:</span> |
||||
|
<t t-esc="line.value"/> |
||||
|
</li> |
||||
|
</t> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<!-- If requiredData is not an object --> |
||||
|
<div t-elif="typeof requiredData !== 'object'"> |
||||
|
<span t-esc="requiredData"/> |
||||
|
</div> |
||||
|
<!-- If requiredData is falsy or an empty object --> |
||||
|
<div t-else=""> |
||||
|
<h6 style="color: #111;">No Data Available !!!</h6> |
||||
|
</div> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,15 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates xml:space="preserve"> |
||||
|
<!-- Inherit and extend the web.TagsList template --> |
||||
|
<t t-inherit="web.TagsList" t-inherit-mode="extension" owl="1"> |
||||
|
<!-- Add tooltip-related attributes to the <span> elements inside the t-foreach loop for visible tags --> |
||||
|
<xpath expr="//t[@t-foreach='visibleTags']/span" position="attributes"> |
||||
|
<!-- Add the data-tooltip-template attribute with the value 'dynamic_hover_on_related_fields.RelatedFieldTooltip' --> |
||||
|
<attribute name="data-tooltip-template">dynamic_hover_on_related_fields.RelatedFieldTooltip</attribute> |
||||
|
<!-- Add the t-att-data-tooltip-info attribute with the value from the tag.info expression --> |
||||
|
<attribute name="t-att-data-tooltip-info">tag.info</attribute> |
||||
|
<!-- Add the t-att-data-tooltip-touch-tap-to-show attribute with the value 'true' --> |
||||
|
<attribute name="t-att-data-tooltip-touch-tap-to-show">true</attribute> |
||||
|
</xpath> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,37 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<templates xml:space="preserve"> |
||||
|
<!-- Inherit and extend the web.FieldTooltip template --> |
||||
|
<t t-inherit="web.FieldTooltip" t-inherit-mode="extension" owl="1"> |
||||
|
<!-- Add content after the existing <ul> element --> |
||||
|
<xpath expr="//ul" position="after"> |
||||
|
<!-- If requiredData is truthy and not an empty array --> |
||||
|
<div t-if="requiredData and requiredData.length !== 0" style="color: #111;"> |
||||
|
<h6 style="color: #111;">Field Data</h6> |
||||
|
<!-- Iterate over each data object in requiredData --> |
||||
|
<t t-foreach="requiredData" t-as="data" t-key="data_index"> |
||||
|
<ul class="o-tooltip--technical"> |
||||
|
<!-- If requiredData has more than one item, display a record index --> |
||||
|
<span t-if="requiredData.length > 1">--> Record - <t t-esc="data_index+1"/> </span> |
||||
|
<t t-foreach="data" t-as="line" t-key="line.id"> |
||||
|
<!-- Iterate over each line in the current data object --> |
||||
|
<li t-if="line.ttype === 'binary'"> |
||||
|
<!-- Handle binary data --> |
||||
|
<span class="o-tooltip--technical--title" t-esc="line.field"/><span>:</span> |
||||
|
<img t-attf-src="data:image/png;base64,#{line.value}" style="width:40px; padding:5px;" t-att-alt="line.field"/> |
||||
|
</li> |
||||
|
<!-- Handle other data types --> |
||||
|
<li t-else=""> |
||||
|
<span class="o-tooltip--technical--title" t-esc="line.field"/><span>:</span> |
||||
|
<t t-esc="line.value"/> |
||||
|
</li> |
||||
|
</t> |
||||
|
</ul> |
||||
|
</t> |
||||
|
</div> |
||||
|
<!-- If requiredData is falsy or an empty array --> |
||||
|
<div t-else=""> |
||||
|
<h6 style="color: #111;">No Data Available !!!</h6> |
||||
|
</div> |
||||
|
</xpath> |
||||
|
</t> |
||||
|
</templates> |
@ -0,0 +1,61 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- View for form configuration --> |
||||
|
<record id="hover_related_fields_view_form" model="ir.ui.view"> |
||||
|
<field name="name">hover.related.fields.view.form</field> |
||||
|
<field name="model">hover.related.fields</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Configure"> |
||||
|
<group> |
||||
|
<group> |
||||
|
<field name="model_ids" invisible="1"/> |
||||
|
<field name="model_id" required="1"/> |
||||
|
<field name="field_ids" widget="many2many_tags" required="1"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- View for tree configuration --> |
||||
|
<record id="hover_related_fields_view_tree" model="ir.ui.view"> |
||||
|
<field name="name">hover.related.fields.view.tree</field> |
||||
|
<field name="model">hover.related.fields</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Configure"> |
||||
|
<field name="model_id"/> |
||||
|
<field name="field_ids" widget="many2many_tags"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- View for search configuration --> |
||||
|
<record id="hover_related_fields_view_search" model="ir.ui.view"> |
||||
|
<field name="name">hover.related.fields.view.search</field> |
||||
|
<field name="model">hover.related.fields</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search string="Filters"> |
||||
|
<field name="model_id" string="Model"/> |
||||
|
<separator/> |
||||
|
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/> |
||||
|
</search> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Action window for configuring hover fields --> |
||||
|
<record id="hover_related_fields_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Configure hover fields</field> |
||||
|
<field name="res_model">hover.related.fields</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
<!-- Main menu item for Dynamic Hover --> |
||||
|
<menuitem |
||||
|
id="hover_related_fields_menu" |
||||
|
web_icon="dynamic_hover_on_related_fields,static/description/icon.png" |
||||
|
name="Dynamic Hover" |
||||
|
/> |
||||
|
<!-- Submenu item for configuring models --> |
||||
|
<menuitem |
||||
|
id="hover_related_fields_menu_configure" |
||||
|
name="Configure Models" |
||||
|
parent="hover_related_fields_menu" |
||||
|
action="hover_related_fields_action" |
||||
|
/> |
||||
|
</odoo> |