diff --git a/advanced_json_widget/README.md b/advanced_json_widget/README.md new file mode 100644 index 000000000..0f5a025f8 --- /dev/null +++ b/advanced_json_widget/README.md @@ -0,0 +1,105 @@ +# Advanced JSON Widget for Odoo 18 + +[![Odoo](https://img.shields.io/badge/Odoo-%23A24689.svg?style=for-the-badge&logo=Odoo&logoColor=white)](https://www.odoo.com) +[![License](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge)](https://opensource.org/licenses/MIT) + +An interactive and intuitive widget for managing JSON fields in Odoo 18, built using the modern OWL JavaScript framework. + +## Overview + +The Advanced JSON Widget is an Odoo module designed to simplify the management of JSON fields by providing an intuitive, interactive interface using OWL, allowing users to view, edit, and organize key-value data seamlessly within the Odoo backend. + +## Features + +- Features +- 🧩 **Interactive JSON Editor**: Easily add, edit, and delete key-value pairs with a user-friendly UI. +- ⚙️ **Seamless Odoo Integration**: Works effortlessly with Odoo 18 models using JSON fields. +- 🚀 **Modern OWL Framework**: Built with Odoo's OWL JavaScript framework for reactive and responsive behavior. +- 💾 **Structured Data Management**: Ensures clean and consistent JSON data storage within your records. +## Screenshots + +Here are some glimpses of Json Widget: + +### User Interface of WebView + +
+ + + Feature 1 + + +
+ + +## Prerequisites + +Before you begin, ensure you have the following installed: + +- An active Odoo Community/Enterprise Edition instance (local or hosted) + +## Installation + +Follow these steps to set up and run the app: + +1. **Clone the Repository** + + ```git clone https://github.com/cybrosystech/Json-Widget.git``` + +2. **Add the module to addons** + + ```cd Json-Widget``` +## Usage + +``` +from odoo import fields, models + +class SomeModel(models.Model): + _name = 'some.model' + + json_data = fields.Json(string="JSON Data") +``` +In the XML view, reference the widget like this: +``` + +``` + +## Contributing + +We welcome contributions! To get started: + +1. Fork the repository. + +2. Create a new branch: + ``` + git checkout -b feature/your-feature-name + ``` +3. Make changes and commit: + ``` + git commit -m "Add your message here" + ``` +4. Push your changes: + ``` + git push origin feature/your-feature-name + ``` +5. Create a Pull Request on GitHub. + +--- +- Submit a pull request with a clear description of your changes. + +## License + +This project is licensed under the LGPL-3. Feel free to use, modify, and distribute it as needed. + +## Contact + +* Mail Contact : odoo@cybrosys.com +* Website : https://cybrosys.com + + +Maintainer +========== +![Cybrosys Logo](https://www.cybrosys.com/images/logo.png) +https://cybrosys.com + +This module is maintained by Cybrosys Technologies. +For support and more information, please visit https://www.cybrosys.com \ No newline at end of file diff --git a/advanced_json_widget/__manifest__.py b/advanced_json_widget/__manifest__.py new file mode 100644 index 000000000..4b63f90a6 --- /dev/null +++ b/advanced_json_widget/__manifest__.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2025-TODAY Cybrosys Technologies() +# Author: Amrithesh 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 JSON Widget', + 'version': '18.0.1.0.0', + 'summary': """Interactive JSON Field Editor Widget for Odoo""", + 'description': """ + This module provides a user-friendly widget for editing JSON data fields in Odoo, + allowing easy management of key-value pairs through an intuitive interface without.""", + 'author': "Cybrosys Techno Solutions", + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': "https://www.cybrosys.com", + 'depends': ['web'], + 'assets': { + 'web.assets_backend': [ + "advanced_json_widget/static/src/**/*" + ], + }, + 'images': ['static/description/banner.jpg'], + 'license': "LGPL-3", + 'installable': True, + 'auto_install': False, +} diff --git a/advanced_json_widget/doc/RELEASE_NOTES.md b/advanced_json_widget/doc/RELEASE_NOTES.md new file mode 100644 index 000000000..02ab0bbbd --- /dev/null +++ b/advanced_json_widget/doc/RELEASE_NOTES.md @@ -0,0 +1,7 @@ +## Module + +#### 03.11.2025 +#### Version 18.0.1.0.0 +##### ADD + +- Initial Commit for Advanced JSON Widget diff --git a/advanced_json_widget/static/description/assets/cybro-icon.png b/advanced_json_widget/static/description/assets/cybro-icon.png new file mode 100644 index 000000000..06e73e11d Binary files /dev/null and b/advanced_json_widget/static/description/assets/cybro-icon.png differ diff --git a/advanced_json_widget/static/description/assets/cybro-odoo.png b/advanced_json_widget/static/description/assets/cybro-odoo.png new file mode 100644 index 000000000..ed02e07a4 Binary files /dev/null and b/advanced_json_widget/static/description/assets/cybro-odoo.png differ diff --git a/advanced_json_widget/static/description/assets/h2.png b/advanced_json_widget/static/description/assets/h2.png new file mode 100755 index 000000000..0bfc4707d Binary files /dev/null and b/advanced_json_widget/static/description/assets/h2.png differ diff --git a/advanced_json_widget/static/description/assets/icons/arrows-repeat.svg b/advanced_json_widget/static/description/assets/icons/arrows-repeat.svg new file mode 100644 index 000000000..1d7efabc5 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/arrows-repeat.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/banner-1.png b/advanced_json_widget/static/description/assets/icons/banner-1.png new file mode 100644 index 000000000..c180db172 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/banner-1.png differ diff --git a/advanced_json_widget/static/description/assets/icons/banner-2.svg b/advanced_json_widget/static/description/assets/icons/banner-2.svg new file mode 100644 index 000000000..e606d97d9 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/banner-2.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/banner-bg.png b/advanced_json_widget/static/description/assets/icons/banner-bg.png new file mode 100644 index 000000000..a8238d3c0 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/banner-bg.png differ diff --git a/advanced_json_widget/static/description/assets/icons/banner-bg.svg b/advanced_json_widget/static/description/assets/icons/banner-bg.svg new file mode 100644 index 000000000..b1378103e --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/banner-bg.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/banner-call.svg b/advanced_json_widget/static/description/assets/icons/banner-call.svg new file mode 100644 index 000000000..96c687e81 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/banner-call.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/banner-mail.svg b/advanced_json_widget/static/description/assets/icons/banner-mail.svg new file mode 100644 index 000000000..cbf0d158d --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/banner-mail.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/banner-pattern.svg b/advanced_json_widget/static/description/assets/icons/banner-pattern.svg new file mode 100644 index 000000000..9c1c7e101 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/banner-pattern.svg @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/banner-promo.svg b/advanced_json_widget/static/description/assets/icons/banner-promo.svg new file mode 100644 index 000000000..d52791b11 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/banner-promo.svg @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/brand-pair.svg b/advanced_json_widget/static/description/assets/icons/brand-pair.svg new file mode 100644 index 000000000..d8db7fc1e --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/brand-pair.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/check.png b/advanced_json_widget/static/description/assets/icons/check.png new file mode 100644 index 000000000..c8e85f51d Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/check.png differ diff --git a/advanced_json_widget/static/description/assets/icons/chevron.png b/advanced_json_widget/static/description/assets/icons/chevron.png new file mode 100644 index 000000000..2089293d6 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/chevron.png differ diff --git a/advanced_json_widget/static/description/assets/icons/close-icon.svg b/advanced_json_widget/static/description/assets/icons/close-icon.svg new file mode 100644 index 000000000..df8cce37a --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/close-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/cogs.png b/advanced_json_widget/static/description/assets/icons/cogs.png new file mode 100644 index 000000000..95d0bad62 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/cogs.png differ diff --git a/advanced_json_widget/static/description/assets/icons/collabarate-icon.svg b/advanced_json_widget/static/description/assets/icons/collabarate-icon.svg new file mode 100644 index 000000000..dd4e10518 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/collabarate-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/advanced_json_widget/static/description/assets/icons/consultation.png b/advanced_json_widget/static/description/assets/icons/consultation.png new file mode 100644 index 000000000..8319d4baa Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/consultation.png differ diff --git a/advanced_json_widget/static/description/assets/icons/cybro-logo.png b/advanced_json_widget/static/description/assets/icons/cybro-logo.png new file mode 100644 index 000000000..ff4b78220 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/cybro-logo.png differ diff --git a/advanced_json_widget/static/description/assets/icons/down.svg b/advanced_json_widget/static/description/assets/icons/down.svg new file mode 100644 index 000000000..f21c36271 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/advanced_json_widget/static/description/assets/icons/ecom-black.png b/advanced_json_widget/static/description/assets/icons/ecom-black.png new file mode 100644 index 000000000..a9385ff13 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/ecom-black.png differ diff --git a/advanced_json_widget/static/description/assets/icons/education-black.png b/advanced_json_widget/static/description/assets/icons/education-black.png new file mode 100644 index 000000000..3eb09b27b Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/education-black.png differ diff --git a/advanced_json_widget/static/description/assets/icons/faq.png b/advanced_json_widget/static/description/assets/icons/faq.png new file mode 100644 index 000000000..4250b5b81 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/faq.png differ diff --git a/advanced_json_widget/static/description/assets/icons/feature-icon.svg b/advanced_json_widget/static/description/assets/icons/feature-icon.svg new file mode 100644 index 000000000..fa0ea6850 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/feature-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/feature.png b/advanced_json_widget/static/description/assets/icons/feature.png new file mode 100644 index 000000000..ac7a785c0 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/feature.png differ diff --git a/advanced_json_widget/static/description/assets/icons/gear.svg b/advanced_json_widget/static/description/assets/icons/gear.svg new file mode 100644 index 000000000..0cc66b6ea --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/gear.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/hero.gif b/advanced_json_widget/static/description/assets/icons/hero.gif new file mode 100644 index 000000000..d28160470 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/hero.gif differ diff --git a/advanced_json_widget/static/description/assets/icons/hire-odoo.svg b/advanced_json_widget/static/description/assets/icons/hire-odoo.svg new file mode 100644 index 000000000..e1ac089b0 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/hire-odoo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/hotel-black.png b/advanced_json_widget/static/description/assets/icons/hotel-black.png new file mode 100644 index 000000000..130f613be Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/hotel-black.png differ diff --git a/advanced_json_widget/static/description/assets/icons/license.png b/advanced_json_widget/static/description/assets/icons/license.png new file mode 100644 index 000000000..a5869797e Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/license.png differ diff --git a/advanced_json_widget/static/description/assets/icons/life-ring-icon.svg b/advanced_json_widget/static/description/assets/icons/life-ring-icon.svg new file mode 100644 index 000000000..3ae6e1d89 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/life-ring-icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/lifebuoy.png b/advanced_json_widget/static/description/assets/icons/lifebuoy.png new file mode 100644 index 000000000..658d56ccc Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/lifebuoy.png differ diff --git a/advanced_json_widget/static/description/assets/icons/mail.svg b/advanced_json_widget/static/description/assets/icons/mail.svg new file mode 100644 index 000000000..1eedde695 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/mail.svg @@ -0,0 +1,3 @@ + + + diff --git a/advanced_json_widget/static/description/assets/icons/manufacturing-black.png b/advanced_json_widget/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 000000000..697eb0e9f Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/manufacturing-black.png differ diff --git a/advanced_json_widget/static/description/assets/icons/notes.png b/advanced_json_widget/static/description/assets/icons/notes.png new file mode 100644 index 000000000..ee5e95404 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/notes.png differ diff --git a/advanced_json_widget/static/description/assets/icons/notification icon.svg b/advanced_json_widget/static/description/assets/icons/notification icon.svg new file mode 100644 index 000000000..053189973 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/notification icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/odoo-consultancy.svg b/advanced_json_widget/static/description/assets/icons/odoo-consultancy.svg new file mode 100644 index 000000000..e05f65bde --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/odoo-consultancy.svg @@ -0,0 +1,4 @@ + + + + diff --git a/advanced_json_widget/static/description/assets/icons/odoo-licencing.svg b/advanced_json_widget/static/description/assets/icons/odoo-licencing.svg new file mode 100644 index 000000000..2606c88b0 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/odoo-licencing.svg @@ -0,0 +1,3 @@ + + + diff --git a/advanced_json_widget/static/description/assets/icons/odoo-logo.png b/advanced_json_widget/static/description/assets/icons/odoo-logo.png new file mode 100644 index 000000000..0e4d0eb5a Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/odoo-logo.png differ diff --git a/advanced_json_widget/static/description/assets/icons/patter.svg b/advanced_json_widget/static/description/assets/icons/patter.svg new file mode 100644 index 000000000..25c9c0a8f --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/patter.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/pattern1.png b/advanced_json_widget/static/description/assets/icons/pattern1.png new file mode 100644 index 000000000..09ab0fb2d Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/pattern1.png differ diff --git a/advanced_json_widget/static/description/assets/icons/pos-black.png b/advanced_json_widget/static/description/assets/icons/pos-black.png new file mode 100644 index 000000000..97c0f90c1 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/pos-black.png differ diff --git a/advanced_json_widget/static/description/assets/icons/puzzle-piece-icon.svg b/advanced_json_widget/static/description/assets/icons/puzzle-piece-icon.svg new file mode 100644 index 000000000..3e9ad9373 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/puzzle-piece-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/puzzle.png b/advanced_json_widget/static/description/assets/icons/puzzle.png new file mode 100644 index 000000000..65cf854e7 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/puzzle.png differ diff --git a/advanced_json_widget/static/description/assets/icons/replace-icon.svg b/advanced_json_widget/static/description/assets/icons/replace-icon.svg new file mode 100644 index 000000000..d0e3a7af1 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/replace-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/restaurant-black.png b/advanced_json_widget/static/description/assets/icons/restaurant-black.png new file mode 100644 index 000000000..4a35eb939 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/restaurant-black.png differ diff --git a/advanced_json_widget/static/description/assets/icons/screenshot-main.png b/advanced_json_widget/static/description/assets/icons/screenshot-main.png new file mode 100644 index 000000000..575f8e676 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/screenshot-main.png differ diff --git a/advanced_json_widget/static/description/assets/icons/screenshot.png b/advanced_json_widget/static/description/assets/icons/screenshot.png new file mode 100644 index 000000000..cef272529 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/screenshot.png differ diff --git a/advanced_json_widget/static/description/assets/icons/service-black.png b/advanced_json_widget/static/description/assets/icons/service-black.png new file mode 100644 index 000000000..301ab51cb Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/service-black.png differ diff --git a/advanced_json_widget/static/description/assets/icons/skype-fill.svg b/advanced_json_widget/static/description/assets/icons/skype-fill.svg new file mode 100644 index 000000000..c17423639 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/skype-fill.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/skype.png b/advanced_json_widget/static/description/assets/icons/skype.png new file mode 100644 index 000000000..51b409fb3 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/skype.png differ diff --git a/advanced_json_widget/static/description/assets/icons/skype.svg b/advanced_json_widget/static/description/assets/icons/skype.svg new file mode 100644 index 000000000..df3dad39b --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/skype.svg @@ -0,0 +1,3 @@ + + + diff --git a/advanced_json_widget/static/description/assets/icons/star-1.svg b/advanced_json_widget/static/description/assets/icons/star-1.svg new file mode 100644 index 000000000..7e55ab162 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/star-1.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/star-2.svg b/advanced_json_widget/static/description/assets/icons/star-2.svg new file mode 100644 index 000000000..5ae9f507a --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/star-2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/support.png b/advanced_json_widget/static/description/assets/icons/support.png new file mode 100644 index 000000000..4f18b8b82 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/support.png differ diff --git a/advanced_json_widget/static/description/assets/icons/test-1 - Copy.png b/advanced_json_widget/static/description/assets/icons/test-1 - Copy.png new file mode 100644 index 000000000..f6a902663 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/test-1 - Copy.png differ diff --git a/advanced_json_widget/static/description/assets/icons/test-1.png b/advanced_json_widget/static/description/assets/icons/test-1.png new file mode 100644 index 000000000..0908add2b Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/test-1.png differ diff --git a/advanced_json_widget/static/description/assets/icons/test-2.png b/advanced_json_widget/static/description/assets/icons/test-2.png new file mode 100644 index 000000000..4671fe91e Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/test-2.png differ diff --git a/advanced_json_widget/static/description/assets/icons/trading-black.png b/advanced_json_widget/static/description/assets/icons/trading-black.png new file mode 100644 index 000000000..9398ba2f1 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/trading-black.png differ diff --git a/advanced_json_widget/static/description/assets/icons/training.png b/advanced_json_widget/static/description/assets/icons/training.png new file mode 100644 index 000000000..884ca024d Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/training.png differ diff --git a/advanced_json_widget/static/description/assets/icons/translate.svg b/advanced_json_widget/static/description/assets/icons/translate.svg new file mode 100644 index 000000000..af9c8a1aa --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/translate.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/update.png b/advanced_json_widget/static/description/assets/icons/update.png new file mode 100644 index 000000000..ecbc5a01a Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/update.png differ diff --git a/advanced_json_widget/static/description/assets/icons/user.png b/advanced_json_widget/static/description/assets/icons/user.png new file mode 100644 index 000000000..6ffb23d9f Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/user.png differ diff --git a/advanced_json_widget/static/description/assets/icons/video.png b/advanced_json_widget/static/description/assets/icons/video.png new file mode 100644 index 000000000..576705b17 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/video.png differ diff --git a/advanced_json_widget/static/description/assets/icons/whatsapp.png b/advanced_json_widget/static/description/assets/icons/whatsapp.png new file mode 100644 index 000000000..d513a5356 Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/whatsapp.png differ diff --git a/advanced_json_widget/static/description/assets/icons/wrench-icon.svg b/advanced_json_widget/static/description/assets/icons/wrench-icon.svg new file mode 100644 index 000000000..174b5a465 --- /dev/null +++ b/advanced_json_widget/static/description/assets/icons/wrench-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/advanced_json_widget/static/description/assets/icons/wrench.png b/advanced_json_widget/static/description/assets/icons/wrench.png new file mode 100644 index 000000000..6c04dea0f Binary files /dev/null and b/advanced_json_widget/static/description/assets/icons/wrench.png differ diff --git a/advanced_json_widget/static/description/assets/modules/b1.png b/advanced_json_widget/static/description/assets/modules/b1.png new file mode 100644 index 000000000..6e617f3d3 Binary files /dev/null and b/advanced_json_widget/static/description/assets/modules/b1.png differ diff --git a/advanced_json_widget/static/description/assets/modules/b2.png b/advanced_json_widget/static/description/assets/modules/b2.png new file mode 100644 index 000000000..696582fa8 Binary files /dev/null and b/advanced_json_widget/static/description/assets/modules/b2.png differ diff --git a/advanced_json_widget/static/description/assets/modules/b3.png b/advanced_json_widget/static/description/assets/modules/b3.png new file mode 100644 index 000000000..cf81c09f8 Binary files /dev/null and b/advanced_json_widget/static/description/assets/modules/b3.png differ diff --git a/advanced_json_widget/static/description/assets/modules/b4.png b/advanced_json_widget/static/description/assets/modules/b4.png new file mode 100644 index 000000000..206e14c47 Binary files /dev/null and b/advanced_json_widget/static/description/assets/modules/b4.png differ diff --git a/advanced_json_widget/static/description/assets/modules/b5.png b/advanced_json_widget/static/description/assets/modules/b5.png new file mode 100644 index 000000000..1b0ce4674 Binary files /dev/null and b/advanced_json_widget/static/description/assets/modules/b5.png differ diff --git a/advanced_json_widget/static/description/assets/modules/b6.png b/advanced_json_widget/static/description/assets/modules/b6.png new file mode 100644 index 000000000..0249a98f1 Binary files /dev/null and b/advanced_json_widget/static/description/assets/modules/b6.png differ diff --git a/advanced_json_widget/static/description/assets/screenshots/ui.png b/advanced_json_widget/static/description/assets/screenshots/ui.png new file mode 100644 index 000000000..a19adc93e Binary files /dev/null and b/advanced_json_widget/static/description/assets/screenshots/ui.png differ diff --git a/advanced_json_widget/static/description/assets/y18.jpg b/advanced_json_widget/static/description/assets/y18.jpg new file mode 100755 index 000000000..eea1714f2 Binary files /dev/null and b/advanced_json_widget/static/description/assets/y18.jpg differ diff --git a/advanced_json_widget/static/description/banner.jpg b/advanced_json_widget/static/description/banner.jpg new file mode 100644 index 000000000..3ba270310 Binary files /dev/null and b/advanced_json_widget/static/description/banner.jpg differ diff --git a/advanced_json_widget/static/description/icon.png b/advanced_json_widget/static/description/icon.png new file mode 100644 index 000000000..07021d285 Binary files /dev/null and b/advanced_json_widget/static/description/icon.png differ diff --git a/advanced_json_widget/static/description/index.html b/advanced_json_widget/static/description/index.html new file mode 100644 index 000000000..2623caf90 --- /dev/null +++ b/advanced_json_widget/static/description/index.html @@ -0,0 +1,797 @@ + + + + + + Advanced JSON Widget + + + + + + + + + + +
+
+ + + +
+
+ Community +
+
+ Enterprise +
+
+ Odoo.sh +
+
+
+ +
+
+
+
+

+ The Advanced JSON Widget adds an intuitive OWL-based interface to easily view and edit JSON + fields in Odoo. +

+

Advanced JSON Widget +

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

Key + Highlights

+
+
+
+
+ +
+
+ Interactive JSON Editor. +
+

+

+
+
+
+
+
+ +
+
+ Seamless Odoo Integration. +
+

+

+
+
+
+
+
+ +
+
+ Modern OWL Framework. +
+

+

+
+
+
+
+ +
+
+
+ Advanced JSON Widget +

+ Are you ready to make your business more + organized? +
Improve now! +

+ +
+
+ +
+
+
+ + + + +
+
+ +
+
+
+
+ acc_bg +
+ +
+
+
+
+

+ Add a JSON field and include it in the + form view. +

+
+
+
+ +
+
+ + + + some_model.py +
+
+
+from odoo import fields, models
+class SomeModel(models.Model):
+    _name = 'some.model'
+    json_data = fields.Json(string="JSON Data")
+
+
+
+ + +
+
+ + + + form_view.xml +
+
+
+<field name="json_data" widget="json_widget"/>
+
+
+
+
+
+
+
+
+
+
+
+
+

+ User Interface of the + + JSON Widget. +

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

+ Easily add, edit, and delete key-value pairs with a user-friendly UI. +

+
+
+
+
+
+
+
+ +
+

+ Ensures clean and consistent JSON data storage within your records. +

+
+ +
+
+
+
+
+
+ +
+

+ Works effortlessly with Odoo 18 models using JSON fields. +

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

+ Related Products +

+ +
+ + +
+

+ Our Services

+
+ +
+
+ .... +
+
+ +
+ + +
+
+ + + + + + diff --git a/advanced_json_widget/static/src/components/json_widget/json_widget.js b/advanced_json_widget/static/src/components/json_widget/json_widget.js new file mode 100644 index 000000000..58c41feb5 --- /dev/null +++ b/advanced_json_widget/static/src/components/json_widget/json_widget.js @@ -0,0 +1,266 @@ +/** @odoo-module **/ +/** + * JSON widget: custom field widget to edit JSON fields as key/value pairs. + */ +import { registry } from "@web/core/registry"; +import { standardFieldProps } from "@web/views/fields/standard_field_props"; +import { useService } from "@web/core/utils/hooks"; +import { Component, useState, useRef, useExternalListener, onWillUpdateProps } from "@odoo/owl"; +import { Field } from "@web/views/fields/field"; +import { Record } from "@web/model/record"; +import { TagsList } from "@web/core/tags_list/tags_list"; +import { _t } from "@web/core/l10n/translation"; +import { useRecordObserver } from "@web/model/relational_model/utils"; + +const TAG_COLOR_COUNT = 5; +/** + * JSON Widget Component + */ +export class JsonWidget extends Component { + static template = "web.JsonWidget"; + static components = { TagsList, Record, Field }; + static props = { ...standardFieldProps }; + /** + * Component initialization + */ + setup() { + this.notification = useService("notification"); + this.state = useState({ + showDropdown: false, + entries: [], + dropdownReady: false, + isLastEntryValid: true, + hasEmptyKey: false, + hasDuplicateKey: false, + }); + this.jsonDropdown = useRef("jsonDropdown"); + this.onWindowClickListener = (ev) => { + if ( + this.state.showDropdown && + this.jsonDropdown.el && + !this.jsonDropdown.el.contains(ev.target) && + !ev.target.isSameNode(document.documentElement) + ) { + this.closeJsonEditor(); + } + }; + useExternalListener(window, "click", this.onWindowClickListener, true); + this.initializeEntries(); + + useRecordObserver((nextProps) => { + this.initializeEntries(nextProps.data[this.props.name], true); + }); + this.initializeEntries(); // Initial call + onWillUpdateProps((nextProps) => { + if (nextProps.data[this.props.name] !== this.props.data[this.props.name]) { + this.initializeEntries(nextProps.data[this.props.name], true); + } + }); + } + /** + * Initialize entries from JSON data. + * @param {Object} tableData - Optional JSON data. + * @param {boolean} updateProps - Use provided data instead of current record. + */ + initializeEntries(tableData, updateProps = false) { + const jsonData = updateProps ? tableData || {} : this.props.record.data[this.props.name]; + this.state.entries = this.formatJsonToEntries(jsonData); + } + /** + * Convert JSON object to array of key-value entries. + */ + formatJsonToEntries(jsonData) { + return Object.entries(jsonData || {}).map(([key, value], index) => ({ + index, + id: `line_${index}`, + key, + value: typeof value === "object" ? JSON.stringify(value) : String(value), + })); + } + /** + * Convert entries array back to JSON object. + */ + formatEntriesToJson() { + return this.state.entries + .filter((entry) => entry.key) + .reduce((acc, entry) => { + try { + const value = entry.value.startsWith("{") || entry.value.startsWith("[") + ? JSON.parse(entry.value) + : entry.value; + acc[entry.key.trim()] = value; + } catch { + acc[entry.key.trim()] = entry.value; + } + return acc; + }, {}); + } + /** + * Update the record field with JSON data. + */ + async updateRecord() { + const jsonData = this.formatEntriesToJson(); + await this.props.record.update({ [this.props.name]: jsonData }); + this.state.isLastEntryValid = true; + this.state.hasDuplicateKey = false; + this.state.hasEmptyKey = false; + } + /** + * Handle Escape key to close editor. + */ + onWidgetKeydown(ev) { + if (ev.key === "Escape") { + this.closeJsonEditor(); + } + } + /** + * Open the JSON editor dropdown. + */ + async openJsonEditor() { + if (!this.props.readonly) { + this.state.showDropdown = true; + await Promise.resolve(); + this.state.dropdownReady = true; + } + } + /** + * Close the JSON editor and update record. + */ + async closeJsonEditor() { + await this.updateRecord(); + this.state.showDropdown = false; + } + /** + * Add a new empty line. + */ + addLine() { + const lastEntry = this.state.entries[this.state.entries.length - 1]; + this.state.isLastEntryValid = this.state.entries.length === 0 || !!lastEntry?.key; + + if (this.state.isLastEntryValid) { + const newId = `line_${this.state.entries.length}`; + this.state.entries.push({ id: newId, key: "", value: "" }); + } else { + const textInputs = this.jsonDropdown.el?.querySelectorAll('input[type="text"]') || []; + if (this.state.hasDuplicateKey) { + this.notification.add(_t("Duplicate keys are not allowed"), { type: "warning" }); + } else if (this.state.hasEmptyKey) { + this.notification.add(_t("Key cannot be empty"), { type: "warning" }); + } else { + this.notification.add(_t("Empty entry not allowed"), { type: "warning" }); + } + textInputs[textInputs.length - 2]?.focus(); + } + } + /** + * Delete a line by index. + */ + async deleteLine(index) { + if (typeof index === "number") { + this.state.entries.splice(index, 1); + } else { + this.state.entries.pop(); + } + await this.updateRecord(); + } + /** + * Validate entry: no empty key and no duplicates. + */ + validateEntry(entry) { + const keys = this.state.entries.map((e) => e.key); + const isDuplicate = keys.filter((k) => k === entry.key).length > 1; + + if (entry.key && entry.value) { + if (isDuplicate) { + this.state.hasDuplicateKey = true; + this.notification.add(_t("Duplicate keys are not allowed"), { type: "warning" }); + return false; + } + this.state.hasDuplicateKey = false; + this.state.hasEmptyKey = false; + return true; + } else if (entry.value && !entry.key) { + this.state.hasEmptyKey = true; + this.notification.add(_t("Key cannot be empty"), { type: "warning" }); + return false; + } + return true; + } + /** + * Update a specific entry. + */ + async updateEntry(record, changes, entry) { + const idx = this.state.entries.findIndex((e) => e.id === entry.id); + if (idx !== -1) { + this.state.entries[idx] = { ...this.state.entries[idx], ...changes }; + if (this.state.entries[idx].key && this.state.entries[idx].value) { + await this.updateRecord(); + } + } + } + /** + * Create props for Record component. + */ + recordProps(entry) { + const fields = { + key: { string: _t("Key"), type: "char" }, + value: { string: _t("Value"), type: "char" }, + }; + return { + fields, + values: { key: entry.key || "", value: entry.value === "false" ? "" : entry.value }, + activeFields: fields, + onRecordChanged: async (record, changes) => { + if (this.validateEntry({ ...entry, ...changes })) { + await this.updateEntry(record, changes, entry); + } + }, + }; + } + /** + * Tags to display summary of JSON. + */ + jsonSummaryTags() { + const jsonData = this.props.record.data[this.props.name] || {}; + return Object.keys(jsonData).map((key, index) => ({ + id: `tag_${index + 1}`, + text: key, + colorIndex: (index % TAG_COLOR_COUNT) + 1, + onClick: (ev) => this.handleTagClick(ev), + })); + } + /** + * Handle tag click to open editor. + */ + async handleTagClick(ev) { + ev.preventDefault(); + ev.stopPropagation(); + await this.openJsonEditor(); + await Promise.resolve(); + + const firstInput = this.jsonDropdown.el?.querySelector('input[type="text"]'); + firstInput?.focus(); + } + /** + * Focus first input when dropdown mounted. + */ + onDropdownMounted() { + if (this.state.dropdownReady) { + const firstInput = this.jsonDropdown.el?.querySelector('input[type="text"]'); + firstInput?.focus(); + } + } +} +/** + * Field definition for JsonWidget. + */ +export const jsonField = { + component: JsonWidget, + displayName: _t("JSON Editor"), + supportedTypes: ["json"], + extractProps: ({ attrs }) => ({ + readonly: attrs.readonly === "true", + }), +}; + +registry.category("fields").add("json_widget", jsonField); \ No newline at end of file diff --git a/advanced_json_widget/static/src/components/json_widget/json_widget.xml b/advanced_json_widget/static/src/components/json_widget/json_widget.xml new file mode 100644 index 000000000..ce1d4be9e --- /dev/null +++ b/advanced_json_widget/static/src/components/json_widget/json_widget.xml @@ -0,0 +1,96 @@ + + + +
+ +
+
+ + Click to add data + +
+ +
+
+
+ + + +
\ No newline at end of file