diff --git a/master_search_systray/README.rst b/master_search_systray/README.rst new file mode 100755 index 000000000..1290c55f0 --- /dev/null +++ b/master_search_systray/README.rst @@ -0,0 +1,43 @@ +.. image:: https://img.shields.io/badge/license-LGPL--3-green.svg + :target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 + +Advanced Search In Systray +========================== +* Master Search Systray enables Users to search the records based on name in any Module. + +Company +------- +* `Cybrosys Techno Solutions `__ + +License +------- +General Public License, Version 3 (LGPL v3). +(https://www.gnu.org/licenses/lgpl-3.0-standalone.html) + + +Credits +------- +Developer: Anfas Faisal 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 `__ + +Further information +=================== +HTML Description: `` \ No newline at end of file diff --git a/master_search_systray/__init__.py b/master_search_systray/__init__.py new file mode 100755 index 000000000..f2a57d83d --- /dev/null +++ b/master_search_systray/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Anfas Faisal 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 . +# +############################################################################# +from . import controllers +from . import models diff --git a/master_search_systray/__manifest__.py b/master_search_systray/__manifest__.py new file mode 100755 index 000000000..499e51d33 --- /dev/null +++ b/master_search_systray/__manifest__.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Anfas Faisal 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 . +# +############################################################################# +{ + 'name': 'Advanced Search In Systray', + 'version': '17.0.1.0.0', + 'category': 'Extra Tools', + 'summary': "Advanced Search in Systray enables Users to search the records" + "based on name in any Module.", + 'description': "The Advanced Search Systray is a feature-rich Odoo module " + "designed to elevate the search experience for users. With " + "a focus on simplicity and effectiveness, this tool allows " + "users to conduct searches seamlessly across all modules " + "within the Odoo platform.", + 'author': "Cybrosys Techno Solutions", + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'depends': ['base'], + 'website': "https://www.cybrosys.com", + 'data': [ + 'views/res_config_settings_views.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'master_search_systray/static/src/css/style.css', + 'master_search_systray/static/src/scss/master_search_bar.scss', + 'master_search_systray/static/src/xml/master_search_icon.xml', + 'master_search_systray/static/src/js/master_search_icon.js', + 'master_search_systray/static/src/js/MasterSearchDialog.js', + 'master_search_systray/static/src/xml/MasterSearchDialog.xml' + ], + }, + 'images': ['static/description/banner.jpg'], + 'license': 'LGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/master_search_systray/controllers/__init__.py b/master_search_systray/controllers/__init__.py new file mode 100755 index 000000000..0c9489c42 --- /dev/null +++ b/master_search_systray/controllers/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Anfas Faisal 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 . +# +############################################################################# +from . import master_search_systray diff --git a/master_search_systray/controllers/master_search_systray.py b/master_search_systray/controllers/master_search_systray.py new file mode 100755 index 000000000..aeb6fa553 --- /dev/null +++ b/master_search_systray/controllers/master_search_systray.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Anfas Faisal 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 . +# +############################################################################# +import psycopg2 +from ast import literal_eval +from odoo import http +from odoo.http import request + + +class MasterSearch(http.Controller): + """Controller for the master search functionality.""" + + @http.route("/master/search", methods=["POST"], type="json", + auth="user") + def master_search(self, query): + """ + Perform a master search across all models in the system based on the + given query. + + This method performs a search across multiple models in the Odoo + system using the provided query string. The search is conducted on + all stored fields within the models associated with the installed + modules configured in the system. + """ + data = [] + # Check if the query is not empty + if query != '': + # Get all models in the system in the res.config.settings + config_settings = request.env['ir.config_parameter'].sudo().get_param( + 'master_search_systray.master_search_installed_ids') + if config_settings: + config_settings_str = literal_eval(config_settings) + # Convert to list of integers + config_settings_ids = [int(id_str) for id_str in config_settings_str] + # Fetch ir.module.module records for the selected module IDs + config_modules = request.env['ir.module.module'].sudo().search([ + ('id', 'in', config_settings_ids)]) + # Collect module names from master_search_values + module_names = [module.name for module in config_modules] + # Fetch ir.module.module records for the selected module names + modules = request.env['ir.module.module'].sudo().search([ + ('name', 'in', module_names)]) + for module in modules: + models = request.env['ir.model'].sudo().search([]) + filtered_models = models.filtered( + lambda m: module.name in m.modules) + # Loop through each model to perform the search + for rec in filtered_models: + # Filter out fields that are not stored in the database + fields = rec.field_id.filtered(lambda f: f.store).mapped('name') + # Check if the model's main name field is in the stored fields + if rec._rec_name in fields: + # Temporary list to store results for the current model + temp_data = [] + try: + # Execute a raw SQL query to search records in the current model + request.env.cr.execute( + "SELECT * FROM %s WHERE name ILIKE '%s'" % ( + rec.model.replace('.', '_'), '%' + query + '%')) + # Fetch the results as a list of dictionaries + records = request.env.cr.dictfetchall() + # If there are matching records, process and append them to temp_data + if len(records) >= 1: + temp_data.append({ + 'title': rec.name, + 'name': None, + 'id': None, + 'isChild': False, + 'isParent': True, + 'model': rec.model + }) + for val in records: + temp_data.append({ + 'title': None, + 'name': val['name'], + 'id': val['id'], + 'isChild': True, + 'isParent': False, + 'model': rec.model + }) + # Append temp_data to the main result data + if records: + data.append(temp_data) + request.env.cr.commit() + except psycopg2.Error: + request.env.cr.rollback() + try: + # If an exception occurs, attempt to perform a search using Odoo API + records = request.env[rec.model].search( + [('name', 'ilike', query)]) + temp_data = [] + # If there are matching records, process and append them to temp_data + if records: + temp_data.append({ + 'title': rec.name, + 'name': None, + 'id': None, + 'isChild': False, + 'isParent': True, + 'model': rec.model + }) + for val in records: + temp_data.append({ + 'title': None, + 'name': val['name'], + 'id': val['id'], + 'isChild': True, + 'isParent': False, + 'model': rec.model + }) + data.append(temp_data) + request.env.cr.commit() + except Exception as e: + request.env.cr.rollback() + return data diff --git a/master_search_systray/doc/RELEASE_NOTES.md b/master_search_systray/doc/RELEASE_NOTES.md new file mode 100755 index 000000000..b8b496985 --- /dev/null +++ b/master_search_systray/doc/RELEASE_NOTES.md @@ -0,0 +1,7 @@ +## Module + +#### 03.06.2023 +#### Version 17.0.1.0.0 +#### ADD + +- Initial commit for Advanced Search In Systray diff --git a/master_search_systray/models/__init__.py b/master_search_systray/models/__init__.py new file mode 100755 index 000000000..e56092e8c --- /dev/null +++ b/master_search_systray/models/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Anfas Faisal 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 . +# +############################################################################# +from . import res_config_settings diff --git a/master_search_systray/models/res_config_settings.py b/master_search_systray/models/res_config_settings.py new file mode 100755 index 000000000..49ff3df58 --- /dev/null +++ b/master_search_systray/models/res_config_settings.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Anfas Faisal 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 . +# +############################################################################# +from odoo import api, fields, models +from ast import literal_eval + + +class ResConfigSettings(models.TransientModel): + """ + This class extends the 'res.config.settings' model in Odoo to add a new + Many2many field for selecting installed modules that will be included in + the master search functionality. + """ + _inherit = "res.config.settings" + + master_search_installed_ids = fields.Many2many( + 'ir.module.module', + string='Installed Modules', + help="Select the installed modules you want to include in the master " + "search.", + domain="[('state', '=', 'installed')]" + ) + + @api.model + def get_values(self): + """ + Retrieve the current values for the configuration settings, including + the selected installed modules for the master search. + """ + res = super(ResConfigSettings, self).get_values() + master_search_installed_ids = self.env[ + 'ir.config_parameter'].sudo().get_param( + 'master_search_systray.master_search_installed_ids') + if master_search_installed_ids: + res.update({ + 'master_search_installed_ids': [ + (6, 0, literal_eval(master_search_installed_ids))] + }) + return res + + def set_values(self): + """ + Save the current values for the configuration settings, including the + selected installed modules for the master search. + """ + res = super(ResConfigSettings, self).set_values() + self.env['ir.config_parameter'].sudo().set_param( + 'master_search_systray.master_search_installed_ids', + self.master_search_installed_ids.ids) + return res diff --git a/master_search_systray/static/description/.vscode/settings.json b/master_search_systray/static/description/.vscode/settings.json new file mode 100644 index 000000000..6f3a2913e --- /dev/null +++ b/master_search_systray/static/description/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} \ No newline at end of file diff --git a/master_search_systray/static/description/assets/icons/capture (1).png b/master_search_systray/static/description/assets/icons/capture (1).png new file mode 100755 index 000000000..8824deafc Binary files /dev/null and b/master_search_systray/static/description/assets/icons/capture (1).png differ diff --git a/master_search_systray/static/description/assets/icons/check.png b/master_search_systray/static/description/assets/icons/check.png new file mode 100755 index 000000000..c8e85f51d Binary files /dev/null and b/master_search_systray/static/description/assets/icons/check.png differ diff --git a/master_search_systray/static/description/assets/icons/chevron.png b/master_search_systray/static/description/assets/icons/chevron.png new file mode 100755 index 000000000..2089293d6 Binary files /dev/null and b/master_search_systray/static/description/assets/icons/chevron.png differ diff --git a/master_search_systray/static/description/assets/icons/cogs.png b/master_search_systray/static/description/assets/icons/cogs.png new file mode 100755 index 000000000..95d0bad62 Binary files /dev/null and b/master_search_systray/static/description/assets/icons/cogs.png differ diff --git a/master_search_systray/static/description/assets/icons/consultation.png b/master_search_systray/static/description/assets/icons/consultation.png new file mode 100755 index 000000000..8319d4baa Binary files /dev/null and b/master_search_systray/static/description/assets/icons/consultation.png differ diff --git a/master_search_systray/static/description/assets/icons/ecom-black.png b/master_search_systray/static/description/assets/icons/ecom-black.png new file mode 100755 index 000000000..a9385ff13 Binary files /dev/null and b/master_search_systray/static/description/assets/icons/ecom-black.png differ diff --git a/master_search_systray/static/description/assets/icons/education-black.png b/master_search_systray/static/description/assets/icons/education-black.png new file mode 100755 index 000000000..3eb09b27b Binary files /dev/null and b/master_search_systray/static/description/assets/icons/education-black.png differ diff --git a/master_search_systray/static/description/assets/icons/hotel-black.png b/master_search_systray/static/description/assets/icons/hotel-black.png new file mode 100755 index 000000000..130f613be Binary files /dev/null and b/master_search_systray/static/description/assets/icons/hotel-black.png differ diff --git a/master_search_systray/static/description/assets/icons/img.png b/master_search_systray/static/description/assets/icons/img.png new file mode 100755 index 000000000..70197f477 Binary files /dev/null and b/master_search_systray/static/description/assets/icons/img.png differ diff --git a/master_search_systray/static/description/assets/icons/license.png b/master_search_systray/static/description/assets/icons/license.png new file mode 100755 index 000000000..a5869797e Binary files /dev/null and b/master_search_systray/static/description/assets/icons/license.png differ diff --git a/master_search_systray/static/description/assets/icons/lifebuoy.png b/master_search_systray/static/description/assets/icons/lifebuoy.png new file mode 100755 index 000000000..658d56ccc Binary files /dev/null and b/master_search_systray/static/description/assets/icons/lifebuoy.png differ diff --git a/master_search_systray/static/description/assets/icons/manufacturing-black.png b/master_search_systray/static/description/assets/icons/manufacturing-black.png new file mode 100755 index 000000000..697eb0e9f Binary files /dev/null and b/master_search_systray/static/description/assets/icons/manufacturing-black.png differ diff --git a/master_search_systray/static/description/assets/icons/photo-capture.png b/master_search_systray/static/description/assets/icons/photo-capture.png new file mode 100755 index 000000000..06c111758 Binary files /dev/null and b/master_search_systray/static/description/assets/icons/photo-capture.png differ diff --git a/master_search_systray/static/description/assets/icons/pos-black.png b/master_search_systray/static/description/assets/icons/pos-black.png new file mode 100755 index 000000000..97c0f90c1 Binary files /dev/null and b/master_search_systray/static/description/assets/icons/pos-black.png differ diff --git a/master_search_systray/static/description/assets/icons/puzzle.png b/master_search_systray/static/description/assets/icons/puzzle.png new file mode 100755 index 000000000..65cf854e7 Binary files /dev/null and b/master_search_systray/static/description/assets/icons/puzzle.png differ diff --git a/master_search_systray/static/description/assets/icons/restaurant-black.png b/master_search_systray/static/description/assets/icons/restaurant-black.png new file mode 100755 index 000000000..4a35eb939 Binary files /dev/null and b/master_search_systray/static/description/assets/icons/restaurant-black.png differ diff --git a/master_search_systray/static/description/assets/icons/service-black.png b/master_search_systray/static/description/assets/icons/service-black.png new file mode 100755 index 000000000..301ab51cb Binary files /dev/null and b/master_search_systray/static/description/assets/icons/service-black.png differ diff --git a/master_search_systray/static/description/assets/icons/trading-black.png b/master_search_systray/static/description/assets/icons/trading-black.png new file mode 100755 index 000000000..9398ba2f1 Binary files /dev/null and b/master_search_systray/static/description/assets/icons/trading-black.png differ diff --git a/master_search_systray/static/description/assets/icons/training.png b/master_search_systray/static/description/assets/icons/training.png new file mode 100755 index 000000000..884ca024d Binary files /dev/null and b/master_search_systray/static/description/assets/icons/training.png differ diff --git a/master_search_systray/static/description/assets/icons/update.png b/master_search_systray/static/description/assets/icons/update.png new file mode 100755 index 000000000..ecbc5a01a Binary files /dev/null and b/master_search_systray/static/description/assets/icons/update.png differ diff --git a/master_search_systray/static/description/assets/icons/user.png b/master_search_systray/static/description/assets/icons/user.png new file mode 100755 index 000000000..6ffb23d9f Binary files /dev/null and b/master_search_systray/static/description/assets/icons/user.png differ diff --git a/master_search_systray/static/description/assets/icons/wrench.png b/master_search_systray/static/description/assets/icons/wrench.png new file mode 100755 index 000000000..6c04dea0f Binary files /dev/null and b/master_search_systray/static/description/assets/icons/wrench.png differ diff --git a/master_search_systray/static/description/assets/misc/Cybrosys R.png b/master_search_systray/static/description/assets/misc/Cybrosys R.png new file mode 100755 index 000000000..da4058087 Binary files /dev/null and b/master_search_systray/static/description/assets/misc/Cybrosys R.png differ diff --git a/master_search_systray/static/description/assets/misc/email.svg b/master_search_systray/static/description/assets/misc/email.svg new file mode 100755 index 000000000..15291cdc3 --- /dev/null +++ b/master_search_systray/static/description/assets/misc/email.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/master_search_systray/static/description/assets/misc/phone.svg b/master_search_systray/static/description/assets/misc/phone.svg new file mode 100755 index 000000000..b7bd7f251 --- /dev/null +++ b/master_search_systray/static/description/assets/misc/phone.svg @@ -0,0 +1,3 @@ + + + diff --git a/master_search_systray/static/description/assets/misc/star (1) 2.svg b/master_search_systray/static/description/assets/misc/star (1) 2.svg new file mode 100755 index 000000000..5ae9f507a --- /dev/null +++ b/master_search_systray/static/description/assets/misc/star (1) 2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/master_search_systray/static/description/assets/misc/support (1) 1.svg b/master_search_systray/static/description/assets/misc/support (1) 1.svg new file mode 100755 index 000000000..7d37a8f30 --- /dev/null +++ b/master_search_systray/static/description/assets/misc/support (1) 1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/master_search_systray/static/description/assets/misc/support-email.svg b/master_search_systray/static/description/assets/misc/support-email.svg new file mode 100755 index 000000000..eb70370d6 --- /dev/null +++ b/master_search_systray/static/description/assets/misc/support-email.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/master_search_systray/static/description/assets/misc/tick-mark.svg b/master_search_systray/static/description/assets/misc/tick-mark.svg new file mode 100755 index 000000000..2dbb40187 --- /dev/null +++ b/master_search_systray/static/description/assets/misc/tick-mark.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/master_search_systray/static/description/assets/misc/whatsapp 1.svg b/master_search_systray/static/description/assets/misc/whatsapp 1.svg new file mode 100755 index 000000000..0bfaf8fc6 --- /dev/null +++ b/master_search_systray/static/description/assets/misc/whatsapp 1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/master_search_systray/static/description/assets/misc/whatsapp.svg b/master_search_systray/static/description/assets/misc/whatsapp.svg new file mode 100755 index 000000000..b618aea1d --- /dev/null +++ b/master_search_systray/static/description/assets/misc/whatsapp.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/master_search_systray/static/description/assets/modules/1.jpg b/master_search_systray/static/description/assets/modules/1.jpg new file mode 100755 index 000000000..c13b125bc Binary files /dev/null and b/master_search_systray/static/description/assets/modules/1.jpg differ diff --git a/master_search_systray/static/description/assets/modules/2.jpg b/master_search_systray/static/description/assets/modules/2.jpg new file mode 100755 index 000000000..4199fb292 Binary files /dev/null and b/master_search_systray/static/description/assets/modules/2.jpg differ diff --git a/master_search_systray/static/description/assets/modules/3.jpg b/master_search_systray/static/description/assets/modules/3.jpg new file mode 100755 index 000000000..da7a164b0 Binary files /dev/null and b/master_search_systray/static/description/assets/modules/3.jpg differ diff --git a/master_search_systray/static/description/assets/modules/4.png b/master_search_systray/static/description/assets/modules/4.png new file mode 100755 index 000000000..7cea975b4 Binary files /dev/null and b/master_search_systray/static/description/assets/modules/4.png differ diff --git a/master_search_systray/static/description/assets/modules/5.png b/master_search_systray/static/description/assets/modules/5.png new file mode 100755 index 000000000..b97f6e369 Binary files /dev/null and b/master_search_systray/static/description/assets/modules/5.png differ diff --git a/master_search_systray/static/description/assets/modules/6.png b/master_search_systray/static/description/assets/modules/6.png new file mode 100755 index 000000000..a80a0d9dc Binary files /dev/null and b/master_search_systray/static/description/assets/modules/6.png differ diff --git a/master_search_systray/static/description/assets/screenshots/1.png b/master_search_systray/static/description/assets/screenshots/1.png new file mode 100755 index 000000000..3a7cf4aba Binary files /dev/null and b/master_search_systray/static/description/assets/screenshots/1.png differ diff --git a/master_search_systray/static/description/assets/screenshots/10.png b/master_search_systray/static/description/assets/screenshots/10.png new file mode 100644 index 000000000..1a9d1f9a1 Binary files /dev/null and b/master_search_systray/static/description/assets/screenshots/10.png differ diff --git a/master_search_systray/static/description/assets/screenshots/11.png b/master_search_systray/static/description/assets/screenshots/11.png new file mode 100644 index 000000000..3cadeca56 Binary files /dev/null and b/master_search_systray/static/description/assets/screenshots/11.png differ diff --git a/master_search_systray/static/description/assets/screenshots/2.png b/master_search_systray/static/description/assets/screenshots/2.png new file mode 100755 index 000000000..10b64e84d Binary files /dev/null and b/master_search_systray/static/description/assets/screenshots/2.png differ diff --git a/master_search_systray/static/description/assets/screenshots/3.png b/master_search_systray/static/description/assets/screenshots/3.png new file mode 100755 index 000000000..2293c4948 Binary files /dev/null and b/master_search_systray/static/description/assets/screenshots/3.png differ diff --git a/master_search_systray/static/description/assets/screenshots/4.png b/master_search_systray/static/description/assets/screenshots/4.png new file mode 100755 index 000000000..90e596150 Binary files /dev/null and b/master_search_systray/static/description/assets/screenshots/4.png differ diff --git a/master_search_systray/static/description/assets/screenshots/5.png b/master_search_systray/static/description/assets/screenshots/5.png new file mode 100755 index 000000000..226000dfc Binary files /dev/null and b/master_search_systray/static/description/assets/screenshots/5.png differ diff --git a/master_search_systray/static/description/assets/screenshots/6.png b/master_search_systray/static/description/assets/screenshots/6.png new file mode 100755 index 000000000..a098cea47 Binary files /dev/null and b/master_search_systray/static/description/assets/screenshots/6.png differ diff --git a/master_search_systray/static/description/assets/screenshots/hero-v17 (3).gif b/master_search_systray/static/description/assets/screenshots/hero-v17 (3).gif new file mode 100644 index 000000000..3c0dc8be1 Binary files /dev/null and b/master_search_systray/static/description/assets/screenshots/hero-v17 (3).gif differ diff --git a/master_search_systray/static/description/banner.jpg b/master_search_systray/static/description/banner.jpg new file mode 100755 index 000000000..a42983c56 Binary files /dev/null and b/master_search_systray/static/description/banner.jpg differ diff --git a/master_search_systray/static/description/icon.png b/master_search_systray/static/description/icon.png new file mode 100755 index 000000000..35d5cc2e2 Binary files /dev/null and b/master_search_systray/static/description/icon.png differ diff --git a/master_search_systray/static/description/index.html b/master_search_systray/static/description/index.html new file mode 100755 index 000000000..d462321cd --- /dev/null +++ b/master_search_systray/static/description/index.html @@ -0,0 +1,629 @@ + + + + + + + Odoo App 3 Index + + + + + + + + +
+
+
+
+
+ +
+
+
+ Community +
+
+ Enterprise +
+
+ Odoo.sh +
+
+
+
+
+
+

+ Advanced Search In Systray

+

+ The module enables Users to search the records based on name in any Module. +

+
+ +
+
+
+
+
+

Key Highlights +

+
+
+
+
+
+ +
+
+

Advance Search user

+

Enable users to perform advanced searches seamlessly across all modules and menus, allowing them to efficiently retrieve records from any part of the application. . +

+
+
+
+
+
+
+ +
+
+

Intuitive Navigation

+

Upon clicking on a specific record in the search results, users will be seamlessly redirected to the corresponding module or menu, providing a streamlined and intuitive navigation experience. +

+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+

+ Go to Settings then Select Master Search Management

+
+
+
+
+
+
+ +
+
+

+ Please select any modules you want to include in your master search.

+
+
+

Note: Adding too many modules may significantly increase processing time.

+
+
+
+
+
+
+ +
+
+

+ Click on the Search Icon located in the top-right corner of the Systray

+
+
+
+
+
+
+ +
+
+

+ Input your desired search query and click the Search Icon to retrieve relevant results.

+
+
+
+
+
+
+ +
+
+

+ You will get the results from here and by clicking the record from related menus

+
+
+
+
+
+
+ +
+
+

+ Clicking on the record will take you directly to the corresponding menu.

+
+
+
+
+
+
+ +
+
+

+ Clicking on records outside of related menus .

+
+
+
+
+
+
+ +
+
+

+ Clicking on the record will take you directly to the corresponding record.

+
+
+
+ + +
+
+
+
    +
  • + Advance Search user + +
      +
    • Enable users to perform advanced searches seamlessly across all modules and menus, allowing them to efficiently retrieve records from any part of the application.
    • +
    + +
  • + +
  • + Intuitive Navigation +
      +
    • Upon clicking on a specific record in the search results, users will be seamlessly redirected to the corresponding module or menu, providing a streamlined and intuitive navigation experience.
    • +
    . +
  • + + +
+
+
+
+
+
+
Version + 16.0.1.0.0|Released on:25th May 2023 +
+

+ + Initial Commit for Advanced Search In Systray.

+
+
+
+
+
+
+
+

Related Products

+
+
+ +
+
+

Our Services

+ +
+
+
+
+
+
+
+
+ service-icon +
+
+

Odoo Customization

+
+
+
+
+
+
+ service-icon +
+
+

Odoo Implementation

+
+
+
+
+
+
+ service-icon +
+
+

Odoo Support

+
+
+
+
+
+
+ service-icon +
+
+

Hire Odoo Developer

+
+
+
+
+ +
+
+ service-icon +
+
+

Odoo Integration

+
+
+
+
+
+
+ service-icon +
+
+

Odoo Migration

+
+
+
+
+
+
+ service-icon +
+
+

Odoo Consultancy

+
+
+
+
+
+
+ service-icon +
+
+

Odoo Implementation

+
+
+
+
+
+
+ service-icon +
+
+

Odoo Licensing Consultancy

+
+
+
+
+
+
+

Our Industries

+ +
+
+
+
+
+
+ +

Trading

+

Easily procure and sell your products

+
+
+
+
+ +

POS

+

Easy configuration and convivial experience

+
+
+
+
+ +

Education

+

A platform for educational management

+
+
+
+
+ +

Manufacturing

+

Plan, track and schedule your operations

+
+
+
+
+ +

E-commerce & Website

+

Mobile friendly, awe-inspiring product pages

+
+
+
+
+ +

Service Management

+

Keep track of services and invoice

+
+
+
+
+ +

Restaurant

+

Run your bar or restaurant methodically

+
+
+
+
+ +

Hotel Management

+

An all-inclusive hotel management application

+
+
+
+
+
+
+

Support

+
+
+
+
+
+
+
+ +
+ Need + Help? +

Got questions or need help? Get in touch.

+
odoo@cybrosys.com +
+
+
+
+
+
+
+
+ +
+ WhatsApp +

Say hi to us on WhatsApp!

+
+91 + 99456767686
+
+
+
+
+
+
+
+
+ + + + + + diff --git a/master_search_systray/static/src/css/style.css b/master_search_systray/static/src/css/style.css new file mode 100755 index 000000000..f84f187b5 --- /dev/null +++ b/master_search_systray/static/src/css/style.css @@ -0,0 +1,143 @@ +.search-button{ + background-color: white; + color: black; + border-radius: 4px; + border: none; + padding: 0.4rem 0.6rem; + font-size: 25px; +} + +.small-heading{ + padding-bottom: 0.5rem; + font-weight: bold; + margin-bottom: 0.5rem; + border-bottom: 1px solid; + display: flex; + justify-content: space-between; +} +.master-onboard_modal-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100vh; + background: rgba(9, 13, 17, 0.78); + -webkit-backdrop-filter: blur(9px); + backdrop-filter: blur(9px); + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + z-index: 999; +} + +.master_modal-container input { + height: 50px; + outline: none; + border: none; + font-size: 13px !important; + display: block; + width: 100%; + padding: 0.3125rem 0.625rem; + font-weight: 600; + line-height: 1.5; + color: #495057; + background-color: transparent; + background-clip: padding-box; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} + +.master_modal-container .o_input_dropdown { + width: 100%; +} + +.master_modal-container .o_field_tags { + border: none; + width: 100%; + padding: 0 !important; +} + +.master_modal-container .o-autocomplete--input { + display: block; + width: 100%; + padding: 0.375rem 2.25rem 0.375rem 0.75rem; + -moz-padding-start: calc(0.75rem - 3px); + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; + background-image: url(data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e); + background-repeat: no-repeat; + background-position: right 0.75rem center; + background-size: 16px 12px; + border-radius: 0.25rem; + transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +.master_modal-container .modal_content { + border-radius: unset; + background: #FFF; + -webkit-box-shadow: 0px 10px 100px 0px rgba(0, 0, 0, 0.15); + box-shadow: 0px 10px 100px 0px rgba(0, 0, 0, 0.15); +} + +.modal_content-header { + display: block; + border-bottom: none; + padding: 2rem; +} + +.modal_content-header h5 { + color: #222; + font-family: "Inter", sans-serif; + font-size: 25px; + font-weight: 700; +} + +.modal_content-header p { + color: #717684; + font-family: "Inter", sans-serif; + font-size: 16px; + font-weight: 500; + margin-bottom: 0px; +} + +.master-onboard_modal-container .custom-search:focus{ + background-color:#FAF9F6; + +} + +.master_searchview_autocomplete .o_menu_item.dropdown-item.focus{ + padding-bottom: 0.5rem; + font-weight: bold; + margin-bottom: 0.5rem; + border-bottom: 1px solid; + display: flex; + justify-content: space-between; +} + +.master_searchview_autocomplete .menu{ + padding-left: 1rem; +} + +.cy_master-create-icon{ + padding: 0.3rem; + border: 1px solid #151E4E; + border-radius: 50%; +} + +.master_modal-container .dashboard_modal-box{ + bottom : 20%; +} \ No newline at end of file diff --git a/master_search_systray/static/src/js/MasterSearchDialog.js b/master_search_systray/static/src/js/MasterSearchDialog.js new file mode 100755 index 000000000..5ee1baef3 --- /dev/null +++ b/master_search_systray/static/src/js/MasterSearchDialog.js @@ -0,0 +1,217 @@ +/** @odoo-module **/ +import { Component, useRef, useExternalListener, useState} from "@odoo/owl"; +import { _t } from "@web/core/l10n/translation"; +import { Dialog } from "@web/core/dialog/dialog"; +import { useService } from "@web/core/utils/hooks"; +let nextItemId = 1; + +export class MasterSearchDialog extends Component { + setup() { + // Set up the initial state and services. + this.state = useState({ + focusedIndex: 0, + menu_list: [], + result: null, + query: "", + isSearchVisible: false, // Add a state variable to control visibility + }); + this.orm = useService("orm"); + this.inputRef = !this.props.autofocus ? useRef("autofocus") : useAutofocus(); + this.items = useState([]); + this.rpc = useService("rpc"); + this.menuService = useService("menu"); + this.actionService = useService("action"); + this.dialogService = useService("dialog") + useExternalListener(window, "click", this.onWindowClick); + useExternalListener(window, "keydown", this.onWindowKeydown); + } + + toggleSearchVisibility() { + // Toggle the visibility of the search bar. + this.state.isSearchVisible = !this.state.isSearchVisible; + } + + selectItem(item) { + this.props.close() + // Handle the selection of an item in the search results. + if (item.isChild) { + this.state.isSearchVisible = false; + this.actionService.doAction( + { + res_model: item.model, + res_id: item.rec_id, + target: "current", + type: "ir.actions.act_window", + views: [[false, "form"]], + }, + ); + } else { + this.resetState(); + } + } + + async computeState(options = {}) { + // Compute the state based on the provided options. + const query = "query" in options ? options.query : this.state.query; + const focusedIndex = "focusedIndex" in options ? options.focusedIndex : this.state.focusedIndex; + this.state.query = query; + this.state.focusedIndex = focusedIndex; + this.inputRef.el.value = query; + const result = await this.rpc("/master/search", { + query: query, + }); + const trimmedQuery = this.state.query.trim(); + this.items.length = 0; + if (!trimmedQuery) { + this.render(); + return; + } + if (result.length != 0) { + for (const record of result) { + var temp_items = []; + for (const rec of record) { + temp_items.push({ + id: nextItemId++, + name: rec.name, + title: rec.title, + rec_id: rec.id, + isChild: rec.isChild, + isParent: rec.isParent, + model: rec.model, + }); + } + this.items.push(temp_items); + } + this.render(); + } else { + this.items = []; + this.render(); + } + } + + resetState() { + // Reset the state of the search bar. + this.computeState({ + focusedIndex: 0, + query: "", + }); + this.inputRef.el.focus(); + } + + // * Handles the search input event. + //This method is triggered when the user types in the search input field. It fetches + //* the menu items and records results based on the query and updates the state with the + //* combined results. If the query is empty, it resets the state and clears the items. + async onSearchInput(ev) { + const query = this.inputRef.el.value; + if (query.trim()) { + const [menuItems, serverResults] = await Promise.all([ + this.fetchMenuItems(query), + this.fetchServerResults(query), + + ]); + this.state.items = [...menuItems, ...serverResults]; + this.computeState({ + query, + focusedIndex: 0, + }); + } else if (this.items.length) { + this.resetState(); + this.state.items = []; + } + } + + + async fetchMenuItems(query) { + //Fetches menu items based on the query. + //This method searches through the available menu items and filters them + //based on the query string. It returns a list of matching menu items. + const app_list = this.menuService.getAll(); + const menu_list = []; + const apps = this.menuService.getApps(); + let app_name = ""; + for (const app_list_item of app_list) { + if ( + app_list_item.id !== "root" && + app_list_item.actionModel !== false && + app_list_item.name.toLowerCase().match(new RegExp(query.trim().toLowerCase().replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'))) + ) { + const app = apps.find((app) => app.appID === app_list_item.appID); + if (app) { + app_name = app.name; + } + menu_list.push({ + id: app_list_item.id, + name: `${app_name}/${app_list_item.name}`, + actionModel: app_list_item.actionModel, + class: "", + }); + } + } + return menu_list; + } + async fetchServerResults(query) { + // * Fetches search results from the records based on the query. + const result = await this.rpc("/master/search", { + query: query, + }); + + const trimmedQuery = query.trim(); + const serverResults = []; + + if (!trimmedQuery) { + return serverResults; + } + + if (result.length !== 0) { + for (const record of result) { + const temp_items = []; + for (const rec of record) { + temp_items.push({ + id: nextItemId++, + name: rec.name, + title: rec.title, + rec_id: rec.id, + isChild: rec.isChild, + isParent: rec.isParent, + model: rec.model, + }); + } + serverResults.push(temp_items); + } + } + return serverResults; + } + + onWindowClick(ev) { + this.props.close() + // Handle clicks on the window. + if (this.items.length) { + this.resetState(); + } + } + onWindowKeydown(ev) { + // Check if the pressed key is the "Esc" key + if (ev.key === "Escape") { + this.onClickMenu(); + } + } + onClickMenu() { + this.props.close() + } + onSearchIconClick() { + // Handle clicks on the search icon. + this.dialogService.add(MasterSearchDialog) + this.toggleSearchVisibility(); + } + onCLickMasterModal(ev){ + ev.stopPropagation() + } + closeSearch() { + // Close the search bar. + this.state.isSearchVisible = false; + } +} + +MasterSearchDialog.template = "master_search_systray.MasterSearchDialog" +MasterSearchDialog.components = { Dialog } \ No newline at end of file diff --git a/master_search_systray/static/src/js/master_search_icon.js b/master_search_systray/static/src/js/master_search_icon.js new file mode 100755 index 000000000..72f5de623 --- /dev/null +++ b/master_search_systray/static/src/js/master_search_icon.js @@ -0,0 +1,20 @@ +/** @odoo-module **/ +import { registry } from "@web/core/registry"; +import { Component } from "@odoo/owl"; +import { useService } from "@web/core/utils/hooks"; +import { MasterSearchDialog } from "./MasterSearchDialog" + +export class SearchBarSystray extends Component { + + // Component for the search bar in the systray. + setup() { + this.dialogService = useService("dialog") + } + onSearchIconClick() { + // Handle clicks on the search icon. + this.dialogService.add(MasterSearchDialog) + } +} +SearchBarSystray.template = "master_search_systray.SearchBarSystray"; +export const systrayItem = { Component: SearchBarSystray, }; +registry.category("systray").add("SearchBar", systrayItem, { sequence: 1,}); diff --git a/master_search_systray/static/src/scss/master_search_bar.scss b/master_search_systray/static/src/scss/master_search_bar.scss new file mode 100755 index 000000000..d32312940 --- /dev/null +++ b/master_search_systray/static/src/scss/master_search_bar.scss @@ -0,0 +1,76 @@ +.master_searchview_autocomplete { + top: 100%; + + > li { + margin: 5px 0px; + } +} +.master_searchview_input_container { + padding:5px; + display: flex; + position: relative; +} +.master_searchview_input { + border-bottom: 1px solid $o-brand-secondary; + margin-bottom: 15px; + width: 100%; + background-color: #fdfcfc; +} +.o_search_bar_systray{ + align-self: center; + } +.search_bar_style { + border: 1px solid gainsboro !important; + min-width: 100%; + min-height: 40vh; + height:40vh; +display: flex !important;} + +.custom-search{ + background: white; + padding: 0.3125rem 0.625rem; + font-size: 0.875rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + background-color: white; + background-clip: padding-box; + border: 1px solid #ced4da; + appearance: none; + border-radius: 0.5rem; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +.search_div{ +display: flex; +margin: 3%; +} +.search_icon{ +margin-left: 5%; + margin-top: 3%; +} +.create_icon{ +margin-left: 10%; +} +.master_searchview_autocomplete { + @include o-position-absolute(calc(100% + #{$border-width * 3}), 0); + width: 100%; + + .o_menu_item { + align-items: center; + display: flex; + + &.o_indent { + padding-left: 0.5rem; + } + + a { + color: inherit; + &.o_expand { + display: flex; + justify-content: center; + width: 25px; + @include o-position-absolute($left: 0); + } + } + } +} diff --git a/master_search_systray/static/src/xml/MasterSearchDialog.xml b/master_search_systray/static/src/xml/MasterSearchDialog.xml new file mode 100755 index 000000000..c08f45d39 --- /dev/null +++ b/master_search_systray/static/src/xml/MasterSearchDialog.xml @@ -0,0 +1,91 @@ + + + + +
+ +
+
+
diff --git a/master_search_systray/static/src/xml/master_search_icon.xml b/master_search_systray/static/src/xml/master_search_icon.xml new file mode 100755 index 000000000..915993611 --- /dev/null +++ b/master_search_systray/static/src/xml/master_search_icon.xml @@ -0,0 +1,15 @@ + + + + +
+
+
+ +
+
+
+
+
+ diff --git a/master_search_systray/views/ir_model_views.xml b/master_search_systray/views/ir_model_views.xml new file mode 100755 index 000000000..7ca12a6d3 --- /dev/null +++ b/master_search_systray/views/ir_model_views.xml @@ -0,0 +1,15 @@ + + + + + ir.model.view.form.inherit.master.search.systray + + ir.model + + + + + + + + diff --git a/master_search_systray/views/res_config_settings_views.xml b/master_search_systray/views/res_config_settings_views.xml new file mode 100644 index 000000000..0a8598be8 --- /dev/null +++ b/master_search_systray/views/res_config_settings_views.xml @@ -0,0 +1,31 @@ + + + + + + res.config.settings.view.form.inherit.master.search.systray + + res.config.settings + + + + + + + + + + + + + + + \ No newline at end of file