@ -0,0 +1,32 @@ | 
				
			|||
# JSON Widget for Odoo 17 | 
				
			|||
 | 
				
			|||
[](https://www.odoo.com) | 
				
			|||
[](https://opensource.org/licenses/MIT) | 
				
			|||
 | 
				
			|||
An interactive and intuitive widget for managing JSON fields in Odoo 17, built using the modern OWL JavaScript framework. | 
				
			|||
 | 
				
			|||
## Overview | 
				
			|||
 | 
				
			|||
The 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 17 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 | 
				
			|||
 | 
				
			|||
<div> | 
				
			|||
  <tr> | 
				
			|||
    <td align="center"> | 
				
			|||
      <img src="static/description/assets/screenshots/ui.png" alt="Feature 1" width="500" style="border: none;"/> | 
				
			|||
    </td> | 
				
			|||
  </tr> | 
				
			|||
</div> | 
				
			|||
 | 
				
			|||
@ -0,0 +1,43 @@ | 
				
			|||
# -*- coding: utf-8 -*- | 
				
			|||
############################################################################# | 
				
			|||
# | 
				
			|||
#    Cybrosys Technologies Pvt. Ltd. | 
				
			|||
# | 
				
			|||
#    Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | 
				
			|||
#    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 <http://www.gnu.org/licenses/>. | 
				
			|||
# | 
				
			|||
############################################################################# | 
				
			|||
{ | 
				
			|||
    'name': 'JSON Widget Field', | 
				
			|||
    'version': '17.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': [ | 
				
			|||
            "json_widget/static/src/**/*" | 
				
			|||
        ], | 
				
			|||
    }, | 
				
			|||
    'images': ['static/description/banner.jpg'], | 
				
			|||
    'license': "LGPL-3", | 
				
			|||
    'installable': True, | 
				
			|||
    'auto_install': False, | 
				
			|||
} | 
				
			|||
@ -0,0 +1,7 @@ | 
				
			|||
## Module <json_widget> | 
				
			|||
 | 
				
			|||
#### 15.07.2025 | 
				
			|||
#### Version 17.0.1.0.0 | 
				
			|||
##### ADD | 
				
			|||
 | 
				
			|||
- Initial Commit for JSON Widget | 
				
			|||
| 
		 After Width: | Height: | Size: 2.2 KiB  | 
| 
		 After Width: | Height: | Size: 28 KiB  | 
| 
		 After Width: | Height: | Size: 628 KiB  | 
| 
		 After Width: | Height: | Size: 1.1 KiB  | 
| 
		 After Width: | Height: | Size: 210 KiB  | 
| 
		 After Width: | Height: | Size: 209 KiB  | 
| 
		 After Width: | Height: | Size: 109 KiB  | 
| 
		 After Width: | Height: | Size: 495 B  | 
| 
		 After Width: | Height: | Size: 1.0 KiB  | 
| 
		 After Width: | Height: | Size: 624 B  | 
| 
		 After Width: | Height: | Size: 136 KiB  | 
| 
		 After Width: | Height: | Size: 214 KiB  | 
| 
		 After Width: | Height: | Size: 36 KiB  | 
| 
		 After Width: | Height: | Size: 3.6 KiB  | 
| 
		 After Width: | Height: | Size: 310 B  | 
| 
		 After Width: | Height: | Size: 929 B  | 
| 
		 After Width: | Height: | Size: 1.3 KiB  | 
| 
		 After Width: | Height: | Size: 3.3 KiB  | 
| 
		 After Width: | Height: | Size: 1.4 KiB  | 
| 
		 After Width: | Height: | Size: 17 KiB  | 
| 
		 After Width: | Height: | Size: 542 B  | 
| 
		 After Width: | Height: | Size: 576 B  | 
| 
		 After Width: | Height: | Size: 733 B  | 
| 
		 After Width: | Height: | Size: 4.3 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 4.0 KiB  | 
| 
		 After Width: | Height: | Size: 1.7 KiB  | 
| 
		 After Width: | Height: | Size: 383 KiB  | 
| 
		 After Width: | Height: | Size: 2.2 KiB  | 
| 
		 After Width: | Height: | Size: 911 B  | 
| 
		 After Width: | Height: | Size: 1.1 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 600 B  | 
| 
		 After Width: | Height: | Size: 673 B  | 
| 
		 After Width: | Height: | Size: 2.0 KiB  | 
| 
		 After Width: | Height: | Size: 462 B  | 
| 
		 After Width: | Height: | Size: 2.1 KiB  | 
| 
		 After Width: | Height: | Size: 926 B  | 
| 
		 After Width: | Height: | Size: 9.0 KiB  | 
| 
		 After Width: | Height: | Size: 23 KiB  | 
| 
		 After Width: | Height: | Size: 7.0 KiB  | 
| 
		 After Width: | Height: | Size: 878 B  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 653 B  | 
| 
		 After Width: | Height: | Size: 800 B  | 
| 
		 After Width: | Height: | Size: 905 B  | 
| 
		 After Width: | Height: | Size: 189 KiB  | 
| 
		 After Width: | Height: | Size: 4.3 KiB  | 
| 
		 After Width: | Height: | Size: 839 B  | 
| 
		 After Width: | Height: | Size: 1.7 KiB  | 
| 
		 After Width: | Height: | Size: 5.9 KiB  | 
| 
		 After Width: | Height: | Size: 1.6 KiB  | 
| 
		 After Width: | Height: | Size: 34 KiB  | 
| 
		 After Width: | Height: | Size: 26 KiB  | 
| 
		 After Width: | Height: | Size: 3.8 KiB  | 
| 
		 After Width: | Height: | Size: 23 KiB  | 
| 
		 After Width: | Height: | Size: 1.9 KiB  | 
| 
		 After Width: | Height: | Size: 2.3 KiB  | 
| 
		 After Width: | Height: | Size: 427 B  | 
| 
		 After Width: | Height: | Size: 627 B  | 
| 
		 After Width: | Height: | Size: 1.1 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 988 B  | 
| 
		 After Width: | Height: | Size: 3.7 KiB  | 
| 
		 After Width: | Height: | Size: 5.0 KiB  | 
| 
		 After Width: | Height: | Size: 875 B  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 1.0 MiB  | 
| 
		 After Width: | Height: | Size: 89 KiB  | 
| 
		 After Width: | Height: | Size: 544 KiB  | 
| 
		 After Width: | Height: | Size: 1.0 MiB  | 
| 
		 After Width: | Height: | Size: 94 KiB  | 
| 
		 After Width: | Height: | Size: 91 KiB  | 
| 
		 After Width: | Height: | Size: 96 KiB  | 
| 
		 After Width: | Height: | Size: 880 KiB  | 
| 
		 After Width: | Height: | Size: 109 KiB  | 
| 
		 After Width: | Height: | Size: 16 KiB  | 
@ -0,0 +1,797 @@ | 
				
			|||
<!DOCTYPE html> | 
				
			|||
<html lang="en"> | 
				
			|||
<head> | 
				
			|||
    <meta charset="UTF-8"/> | 
				
			|||
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/> | 
				
			|||
    <title>JSON Widget</title> | 
				
			|||
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" | 
				
			|||
          rel="stylesheet"/> | 
				
			|||
    <link rel="preconnect" href="https://fonts.googleapis.com"> | 
				
			|||
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | 
				
			|||
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" | 
				
			|||
          rel="stylesheet"> | 
				
			|||
    <link rel="stylesheet" | 
				
			|||
          href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css"/> | 
				
			|||
    <link rel="stylesheet" | 
				
			|||
          href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.carousel.min.css"/> | 
				
			|||
    <style> | 
				
			|||
        :root { | 
				
			|||
            --primary-color: #7f54b3; | 
				
			|||
            --bg-white: #fff; | 
				
			|||
            --text-color: #121212; | 
				
			|||
            --text-color-light: #64728f; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        body { | 
				
			|||
            font-family: "Montserrat", sans-serif; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        .nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { | 
				
			|||
            color: #121212; | 
				
			|||
            font-family: Montserrat; | 
				
			|||
            font-size: 16px !important; | 
				
			|||
            font-weight: 500 !important; | 
				
			|||
            border-radius: 30px; | 
				
			|||
            line-height: normal; | 
				
			|||
            text-transform: capitalize; | 
				
			|||
            background-color: #F5F5F5; | 
				
			|||
            border: none; | 
				
			|||
            margin-bottom: 0; | 
				
			|||
            padding: 12px 24px; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        .nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover { | 
				
			|||
            border-color: transparent; | 
				
			|||
            isolation: isolate; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        .nav-tabs .nav-link:focus-visible { | 
				
			|||
            border-color: transparent; | 
				
			|||
            box-shadow: none; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        /* owl-carosel */ | 
				
			|||
        .owl-carousel .owl-nav { | 
				
			|||
            position: absolute; | 
				
			|||
            top: 42%; | 
				
			|||
            width: 100%; | 
				
			|||
            display: flex; | 
				
			|||
            justify-content: space-between; | 
				
			|||
            transform: translateY(-42%); | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        .owl-carousel .owl-nav button.owl-prev { | 
				
			|||
            position: absolute; | 
				
			|||
            right: -36px; | 
				
			|||
            font-size: 28px; | 
				
			|||
            background-color: #e4e4e4; | 
				
			|||
            border-radius: 20px; | 
				
			|||
            width: 40px; | 
				
			|||
            height: 40px; | 
				
			|||
            display: flex; | 
				
			|||
            justify-content: center; | 
				
			|||
            align-items: center; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        .owl-carousel .owl-nav button.owl-next { | 
				
			|||
            position: absolute; | 
				
			|||
            left: -36px; | 
				
			|||
            font-size: 28px; | 
				
			|||
            background-color: #e4e4e4; | 
				
			|||
            border-radius: 20px; | 
				
			|||
            width: 40px; | 
				
			|||
            height: 40px; | 
				
			|||
            display: flex; | 
				
			|||
            justify-content: center; | 
				
			|||
            align-items: center; | 
				
			|||
 | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
    </style> | 
				
			|||
</head> | 
				
			|||
<body> | 
				
			|||
<!-- overview --> | 
				
			|||
<div class="container"> | 
				
			|||
    <div class="my-5"> | 
				
			|||
        <!-- button tab --> | 
				
			|||
        <!--  --> | 
				
			|||
        <!-- version support --> | 
				
			|||
        <div class="my-3 d-flex align-items-center justify-content-end"> | 
				
			|||
            <div class="text-center" | 
				
			|||
                 style="background-color:#017E84 !important; font-size:0.8rem !important; color:#fff !important; font-weight:500 !important; padding:4px !important; margin:0 3px !important; border-radius:50px !important; min-width:120px !important"> | 
				
			|||
                Community | 
				
			|||
            </div> | 
				
			|||
            <div class="text-center" | 
				
			|||
                 style="background-color:#875A7B !important; color:#fff !important; font-size:0.8rem !important; font-weight:500 !important; padding:4px !important; margin:0 3px !important; border-radius:50px !important; min-width:120px !important"> | 
				
			|||
                Enterprise | 
				
			|||
            </div> | 
				
			|||
            <div class="text-center" | 
				
			|||
                 style="background-color:#7C7BAD !important; color:#fff !important; font-size:0.8rem !important; font-weight:500 !important; padding:4px !important; margin:0 3px !important; border-radius:50px !important; min-width:120px !important"> | 
				
			|||
                Odoo.sh | 
				
			|||
            </div> | 
				
			|||
        </div> | 
				
			|||
        <div class="tab-content" id="myTabContent"> | 
				
			|||
            <!-- description --> | 
				
			|||
            <div class="tab-pane fade show active" id="home" role="tabpanel" | 
				
			|||
                 aria-labelledby="home-tab"> | 
				
			|||
                <div class="position-relative" | 
				
			|||
                     style="border-radius: 16px; background: #f8f8f8; padding: 20px 0;"> | 
				
			|||
                    <div class="row " style=" | 
				
			|||
          padding: 2rem 0rem 0 !important; | 
				
			|||
        "> | 
				
			|||
                        <div class="col-lg-8 mx-auto gap-4 d-flex flex-column align-items-center"> | 
				
			|||
                            <p class="my-1 text-center text-uppercase" | 
				
			|||
                               style=" | 
				
			|||
              letter-spacing: 4px !important; | 
				
			|||
              color: #7f54b3; | 
				
			|||
              font-weight: bold; | 
				
			|||
              text-align: center; | 
				
			|||
              font-size: 14px; | 
				
			|||
              font-weight: 600; | 
				
			|||
              line-height: 15.96px; | 
				
			|||
              text-transform: uppercase; | 
				
			|||
            "> | 
				
			|||
                                The JSON Widget adds an intuitive OWL-based interface to easily view and edit JSON | 
				
			|||
                                fields in Odoo. | 
				
			|||
                            </p> | 
				
			|||
                            <h1 class="text-center text-uppercase my-0" | 
				
			|||
                                style=" | 
				
			|||
                                  color: #121212; | 
				
			|||
                                  font-size: 46px; | 
				
			|||
                                  font-weight: 700; | 
				
			|||
                                  line-height: normal; | 
				
			|||
                                ">JSON Widget Field</span> | 
				
			|||
                            </h1> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="col-lg-12 d-flex justify-content-center align-items-center" | 
				
			|||
                             style="margin: 3rem 0;"> | 
				
			|||
                            <img src="./assets/icons/brand-pair.svg" | 
				
			|||
                                 width="100%" | 
				
			|||
                                 height="auto" | 
				
			|||
                                 style="width: 50%" | 
				
			|||
                                 class="img-responsive"/> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="col-md-12 text-center"> | 
				
			|||
                            <a href="mailto:odoo@cybrosys.com" | 
				
			|||
                               target="_blank" | 
				
			|||
                               style="background-color: transparent;border-radius: 35px; | 
				
			|||
              font-family: Montserrat; | 
				
			|||
              display: inline-block; | 
				
			|||
              padding: 7px 33px; | 
				
			|||
              border: 1px solid #7f54b3; | 
				
			|||
              color: #7f54b3; | 
				
			|||
              text-decoration: none; | 
				
			|||
            " | 
				
			|||
                               class="mx-1 mb-2 deep-1 deep_hover"> | 
				
			|||
                                <img class="img" | 
				
			|||
                                     style="width: 24px" | 
				
			|||
                                     src="./assets/icons/mail.svg"/> | 
				
			|||
                                <span | 
				
			|||
                                        class="pl-2" | 
				
			|||
                                        style=" font-size: 16px; vertical-align: middle" | 
				
			|||
                                        >Email Us</span | 
				
			|||
                                > | 
				
			|||
                            </a> | 
				
			|||
                            <a href="skype:cybroopenerp?chat" | 
				
			|||
                               target="_blank" | 
				
			|||
                               style=" | 
				
			|||
              background-color: #7f289b; | 
				
			|||
              font-family: Montserrat; | 
				
			|||
              display: inline-block; | 
				
			|||
              padding: 7px 33px; | 
				
			|||
              border: 1px solid #7f289b; | 
				
			|||
              border-radius: 35px; | 
				
			|||
              text-decoration: none; | 
				
			|||
            " | 
				
			|||
                               class="mx-1 mb-2 deep-1 deep_hover"> | 
				
			|||
                                <img | 
				
			|||
                                        class="img" | 
				
			|||
                                        style="width: 24px" | 
				
			|||
                                        src="./assets/icons/skype-fill.svg" | 
				
			|||
                                /> | 
				
			|||
                                <span | 
				
			|||
                                        class="pl-2" | 
				
			|||
                                        style="color: #fff; font-size: 16px; vertical-align: middle" | 
				
			|||
                                >Skype Us</span | 
				
			|||
                                > | 
				
			|||
                            </a> | 
				
			|||
                        </div> | 
				
			|||
                    </div> | 
				
			|||
                    <div class="position-absolute bottom-0" | 
				
			|||
                         style="z-index: 1; width: 100%;"> | 
				
			|||
                        <img src="./assets/icons/banner-bg.svg" | 
				
			|||
                             class="img-fluid w-100"> | 
				
			|||
                    </div> | 
				
			|||
                    <div class="position-absolute bottom-0 end-0" | 
				
			|||
                         style=" z-index: 2;"> | 
				
			|||
                        <img src="./assets/icons/patter.svg"> | 
				
			|||
                    </div> | 
				
			|||
                </div> | 
				
			|||
                <!-- key-highlight --> | 
				
			|||
                <div class="" style="border-radius: 16px; | 
				
			|||
     padding: 60px 40px; | 
				
			|||
     border: 1px solid #EBEEF2; | 
				
			|||
     background: #F5F5F7; | 
				
			|||
     box-shadow: 0px 5px 20px -11px rgba(0, 0, 0, 0.25); "> | 
				
			|||
                    <div class="row"> | 
				
			|||
                        <div class="col-lg-12 d-flex flex-column justify-content-center align-items-center"> | 
				
			|||
                            <h2 style=" color: #121212; | 
				
			|||
            text-align: center; | 
				
			|||
            font-size: 40px; | 
				
			|||
            font-weight: 700; | 
				
			|||
            text-transform: uppercase; padding-bottom: 50px;">Key | 
				
			|||
                                Highlights</h2> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="col-lg-4"> | 
				
			|||
                            <div class="mb-4 d-flex flex-column justify-content-center gap-3" | 
				
			|||
                                 style="border-radius: 12px; border: 1px solid  #B6BCCD; | 
				
			|||
            background:  #FFF;padding:32px "> | 
				
			|||
                                <div class="d-flex justify-content-center align-items-center" | 
				
			|||
                                     style="background-color:#7847D9 !important; border-radius:8px !important; height:42px; width:42px"> | 
				
			|||
                                    <img src="./assets/icons/feature-icon.svg" | 
				
			|||
                                         class="img-responsive" height="26px" | 
				
			|||
                                         width="26px"> | 
				
			|||
                                </div> | 
				
			|||
                                <h5 class="m-0" | 
				
			|||
                                    style="color:#000 !important; font-weight:bold"> | 
				
			|||
                                    Interactive JSON Editor. | 
				
			|||
                                </h5> | 
				
			|||
                                <p class="m-0" | 
				
			|||
                                   style="font-size:0.9rem; color:#64728f; font-size: 16px; font-weight: 400;"> | 
				
			|||
                                </p> | 
				
			|||
                            </div> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="col-lg-4"> | 
				
			|||
                            <div class="mb-4 d-flex flex-column justify-content-center gap-3" | 
				
			|||
                                 style="border-radius: 12px; | 
				
			|||
          border: 1px solid  #B6BCCD; | 
				
			|||
          background:  #FFF;padding:32px "> | 
				
			|||
                                <div class="d-flex justify-content-center align-items-center" | 
				
			|||
                                     style="background-color:#7847D9 !important; border-radius:8px !important; height:42px; width:42px"> | 
				
			|||
                                    <img src="./assets/icons/feature-icon.svg" | 
				
			|||
                                         class="img-responsive" height="26px" | 
				
			|||
                                         width="26px"> | 
				
			|||
                                </div> | 
				
			|||
                                <h5 class="m-0" | 
				
			|||
                                    style="color:#000 !important; font-weight:bold"> | 
				
			|||
                                    Seamless Odoo Integration. | 
				
			|||
                                </h5> | 
				
			|||
                                <p class="m-0" | 
				
			|||
                                   style="font-size:0.9rem; color:#64728f; font-size: 16px; font-weight: 400;"> | 
				
			|||
                                </p> | 
				
			|||
                            </div> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="col-lg-4"> | 
				
			|||
                            <div class="mb-4 d-flex flex-column justify-content-center gap-3" | 
				
			|||
                                 style="border-radius: 12px; | 
				
			|||
          border: 1px solid  #B6BCCD; | 
				
			|||
          background:  #FFF;padding:32px "> | 
				
			|||
                                <div class="d-flex justify-content-center align-items-center" | 
				
			|||
                                     style="background-color:#7847D9 !important; border-radius:8px !important; height:42px; width:42px"> | 
				
			|||
                                    <img src="./assets/icons/feature-icon.svg" | 
				
			|||
                                         class="img-responsive" height="26px" | 
				
			|||
                                         width="26px"> | 
				
			|||
                                </div> | 
				
			|||
                                <h5 class="m-0" | 
				
			|||
                                    style="color:#000 !important; font-weight:bold"> | 
				
			|||
                                    Modern OWL Framework. | 
				
			|||
                                </h5> | 
				
			|||
                                <p class="m-0" | 
				
			|||
                                   style="font-size:0.9rem; color:#64728f; font-size: 16px; font-weight: 400;"> | 
				
			|||
                                </p> | 
				
			|||
                            </div> | 
				
			|||
                        </div> | 
				
			|||
                    </div> | 
				
			|||
                </div> | 
				
			|||
                <!--code  --> | 
				
			|||
                <div class="my-5"> | 
				
			|||
                    <div class="position-relative" | 
				
			|||
                         style=" padding: 5rem 4rem 5rem 4rem; background-color: #0A1425; border-radius: 12px;"> | 
				
			|||
                        <div class="d-flex flex-column gap-4"> | 
				
			|||
                            <span class="wrapper-subtitle" | 
				
			|||
                                  style="font-size: 40px; font-weight: 700; color: #fff;line-height: 60px; text-transform: capitalize; width: 450px;  font-family: Montserrat;">JSON Widget</span> | 
				
			|||
                            <h3 class="wrapper-details" | 
				
			|||
                                style="font-size: 20px; font-weight: 400; color: #fff; line-height: 32px;  "> | 
				
			|||
                                Are you ready to make your business more | 
				
			|||
                                organized? | 
				
			|||
                                <br> Improve now! | 
				
			|||
                            </h3> | 
				
			|||
                            <div class="d-flex gap-3"> | 
				
			|||
                                <a href="mailto:odoo@cybrosys.com" | 
				
			|||
                                   class="shop-btn" style="cursor: pointer; border-radius: 16px; display: flex; justify-content: center; align-items: center; gap: 7px; | 
				
			|||
            border: 1px solid  #ffffff33; | 
				
			|||
            background-color: #ffffff14; | 
				
			|||
            backdrop-filter: blur(10px); color: #fff; padding: 12px 16px 12px 16px; text-decoration: none;"> | 
				
			|||
             <span style="border-radius: 12px; | 
				
			|||
             background-color: #ffffff1a; | 
				
			|||
             backdrop-filter: blur(6px);padding: 12px;  "> | 
				
			|||
              <img src="./assets/icons/banner-mail.svg"> | 
				
			|||
           </span> | 
				
			|||
                                    <span style="font-weight: 500;font-family: Montserrat;">odoo@cybrosys.com</span> | 
				
			|||
                                </a> | 
				
			|||
                                <a href="tel:+91 9074270811" class="shop-btn" | 
				
			|||
                                   style="cursor: pointer; border-radius: 16px; display: flex; justify-content: center; align-items: center; gap: 7px; | 
				
			|||
             border: 1px solid  #ffffff33; | 
				
			|||
             background-color: #ffffff14; | 
				
			|||
            backdrop-filter: blur(10px); color: #fff; padding: 12px 22px 12px 18px; text-decoration: none;"> | 
				
			|||
             <span style="border-radius: 12px; | 
				
			|||
             background-color: #ffffff1a; | 
				
			|||
             backdrop-filter: blur(6px);padding: 12px;"> | 
				
			|||
              <img src="./assets/icons/banner-call.svg"> | 
				
			|||
           </span> | 
				
			|||
                                    <span style="font-weight: 500;font-family: Montserrat;">+91 9074270811</span> | 
				
			|||
                                </a> | 
				
			|||
                            </div> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="position-absolute bottom-0 end-0"> | 
				
			|||
                            <img src="./assets/icons/banner-pattern.svg" | 
				
			|||
                                 style="width: 540px;"> | 
				
			|||
                        </div> | 
				
			|||
                    </div> | 
				
			|||
                </div> | 
				
			|||
                <!-- end-code --> | 
				
			|||
                <!--  --> | 
				
			|||
                <!-- screenshot and other --> | 
				
			|||
 | 
				
			|||
                <div class="mb-4 bg-white" | 
				
			|||
                     style=" border: 1px solid #EBEEF2; border-radius: 6px; box-shadow: 0px 8px 20px -4px rgba(0, 0, 0, 0.10); border: 1px solid #EBEEF2;"> | 
				
			|||
                    <div> | 
				
			|||
                        <ul class="nav nav-tabs justify-content-center bg-white py-2" | 
				
			|||
                            id="myTab" role="tablist" | 
				
			|||
                            style="border-radius: 6px 6px 0 0;"> | 
				
			|||
                            <li class="nav-item"> | 
				
			|||
                                <a aria-controls="overview" | 
				
			|||
                                   aria-bs-selected="true" | 
				
			|||
                                   class="nav-link active" data-bs-toggle="tab" | 
				
			|||
                                   href="#overview" id="overview-tab" role="tab" | 
				
			|||
                                   style="color:#121212; font-weight:500; font-size:16px"> | 
				
			|||
                                    Screenshots</a> | 
				
			|||
                            </li> | 
				
			|||
                            <li class="nav-item"> | 
				
			|||
                                <a aria-controls="feature" | 
				
			|||
                                   aria-bs-selected="false" | 
				
			|||
                                   class="nav-link py-2" data-bs-toggle="tab" | 
				
			|||
                                   href="#feature" id="feature-tab" role="tab" | 
				
			|||
                                   style="color:#121212; font-weight:500; font-size:16px">Features</a> | 
				
			|||
                            </li> | 
				
			|||
                        </ul> | 
				
			|||
                    </div> | 
				
			|||
                    <div class="tab-content p-md-5 p-2 py-3" id="myTabContent2"> | 
				
			|||
                        <div aria-labelledby="overview-tab" | 
				
			|||
                             class="tab-pane fade show active" id="overview" | 
				
			|||
                             role="tabpanel"> | 
				
			|||
                            <div class="position-relative mb-4" | 
				
			|||
                                 style="border-radius:10px"> | 
				
			|||
                                <img alt="acc_bg" | 
				
			|||
                                     class="w-100 h-100 position-absolute img-fluid left_0" | 
				
			|||
                                     loading="lazy" | 
				
			|||
                                     src="//apps.odoocdn.com/apps/assets/17.0/ks_dashboard_ninja/ai-img/o3.png?007008f" | 
				
			|||
                                     style=""> | 
				
			|||
                            </div> | 
				
			|||
                            <!-- screenshots section--> | 
				
			|||
                            <div class="position-relative mb-4" style="border-radius:10px; background-color:#f4f4f4"> | 
				
			|||
                                <div class="p-md-5 p-3 position-relative"> | 
				
			|||
                                    <div class="row"> | 
				
			|||
                                        <div class="col-md-12"> | 
				
			|||
                                            <h1 style="font-weight:bold; font-size:calc(1.1rem + 1vw); line-height:120%; text-align:center; text-transform:capitalize; font-size:40px; font-weight:700;"> | 
				
			|||
                                                <span style="color:#121212; font-size:calc(1.1rem + 1vw)">Add a JSON field and include it in the</span> | 
				
			|||
                                                <span style="color:#7f54b3; font-size:calc(1.1rem + 1vw)">form view.</span> | 
				
			|||
                                            </h1> | 
				
			|||
                                        </div> | 
				
			|||
                                        <div class="col-md-12 text-center"> | 
				
			|||
                                            <div class="d-inline-block p-3 shadow-sm" | 
				
			|||
                                                 style="background-color:#fff; border-radius:10px; text-align:left;"> | 
				
			|||
                                                <!-- first code editor --> | 
				
			|||
                                                <div style="border-radius:10px; overflow:hidden; box-shadow:0 2px 8px rgba(0,0,0,0.15); margin-bottom:20px; font-family:'Courier New', Courier, monospace; background:#2b2b2b;"> | 
				
			|||
                                                    <div style="background:#1e1e1e; color:#ccc; padding:5px 10px; font-size:12px; display:flex; align-items:center;"> | 
				
			|||
                                                        <span style="height:12px; width:12px; background:#ff5f56; border-radius:50%; display:inline-block; margin-right:5px;"></span> | 
				
			|||
                                                        <span style="height:12px; width:12px; background:#ffbd2e; border-radius:50%; display:inline-block; margin-right:5px;"></span> | 
				
			|||
                                                        <span style="height:12px; width:12px; background:#27c93f; border-radius:50%; display:inline-block;"></span> | 
				
			|||
                                                        <span style="margin-left:10px; font-size:11px;">some_model.py</span> | 
				
			|||
                                                    </div> | 
				
			|||
                                                    <div> | 
				
			|||
<pre style="margin:0; padding:15px; color:#f8f8f2; font-size:13px; overflow-x:auto; display:block;"> | 
				
			|||
<span style="color:#66d9ef">from</span> odoo <span style="color:#66d9ef">import</span> fields, models | 
				
			|||
<span style="color:#f92672">class</span> SomeModel(models.Model): | 
				
			|||
    _name = <span style="color:#e6db74">'some.model'</span> | 
				
			|||
    json_data = fields.Json(string=<span style="color:#e6db74">"JSON Data"</span>) | 
				
			|||
</pre> | 
				
			|||
                                                    </div> | 
				
			|||
                                                </div> | 
				
			|||
 | 
				
			|||
                                                <!-- second code editor --> | 
				
			|||
                                                <div style="border-radius:10px; overflow:hidden; box-shadow:0 2px 8px rgba(0,0,0,0.15); font-family:'Courier New', Courier, monospace; background:#2b2b2b;"> | 
				
			|||
                                                    <div style="background:#1e1e1e; color:#ccc; padding:5px 10px; font-size:12px; display:flex; align-items:center;"> | 
				
			|||
                                                        <span style="height:12px; width:12px; background:#ff5f56; border-radius:50%; display:inline-block; margin-right:5px;"></span> | 
				
			|||
                                                        <span style="height:12px; width:12px; background:#ffbd2e; border-radius:50%; display:inline-block; margin-right:5px;"></span> | 
				
			|||
                                                        <span style="height:12px; width:12px; background:#27c93f; border-radius:50%; display:inline-block;"></span> | 
				
			|||
                                                        <span style="margin-left:10px; font-size:11px;">form_view.xml</span> | 
				
			|||
                                                    </div> | 
				
			|||
                                                    <div> | 
				
			|||
<pre style="margin:0; padding:15px; color:#f8f8f2; font-size:13px; overflow-x:auto; display:block;"> | 
				
			|||
<field name=<span style="color:#e6db74">"json_data"</span> widget=<span style="color:#e6db74">"json_widget"</span>/> | 
				
			|||
</pre> | 
				
			|||
                                                    </div> | 
				
			|||
                                                </div> | 
				
			|||
                                            </div> | 
				
			|||
                                        </div> | 
				
			|||
                                    </div> | 
				
			|||
                                </div> | 
				
			|||
                            </div> | 
				
			|||
                            <div class="position-relative mb-4" | 
				
			|||
                                 style="border-radius:10px; background-color:#f4f4f4"> | 
				
			|||
                                <div class="p-md-5 p-3 position-relative"> | 
				
			|||
                                    <div class="row"> | 
				
			|||
                                        <div class="col-md-12"> | 
				
			|||
                                            <h1 style="font-weight:bold; font-size:calc(1.1rem + 1vw); line-height:120%; text-align:center; text-transform:capitalize; font-size: 40px; | 
				
			|||
                              font-weight: 700;"> | 
				
			|||
                                      <span style="color:#121212; font-size:calc(1.1rem + 1vw)">User Interface of the | 
				
			|||
                                      </span> | 
				
			|||
                                                <span style="color: #7f54b3; font-size:calc(1.1rem + 1vw)">JSON Widget.</span> | 
				
			|||
                                            </h1> | 
				
			|||
                                        </div> | 
				
			|||
                                        <div class="col-md-12 text-center"> | 
				
			|||
                                            <div class="d-inline-block p-3 shadow-sm" | 
				
			|||
                                                 style="background-color:#fff; border-radius:10px"> | 
				
			|||
                                                <img alt="" class="img-fluid" | 
				
			|||
                                                     loading="lazy" | 
				
			|||
                                                     src="./assets/screenshots/ui.png" | 
				
			|||
                                                     style="min-height: 1px;"> | 
				
			|||
                                            </div> | 
				
			|||
                                        </div> | 
				
			|||
                                    </div> | 
				
			|||
                                </div> | 
				
			|||
                            </div> | 
				
			|||
                        </div> | 
				
			|||
                        <div aria-labelledby="feature-tab" | 
				
			|||
                             class="tab-pane fade show py-1" id="feature" | 
				
			|||
                             role="tabpanel"> | 
				
			|||
                            <div class="row py-4"> | 
				
			|||
                                <!-- Features Section --> | 
				
			|||
                                <div class="col-md-6 col-sm-12 p-3"> | 
				
			|||
                                    <div class="d-flex flex-column align-items-start h-100" | 
				
			|||
                                         style="padding:30px; border-radius:12px; background-color:#faf8ff"> | 
				
			|||
                                        <div class="d-flex align-items-center justify-content-center"> | 
				
			|||
                                            <div class="d-flex align-items-center justify-content-center " | 
				
			|||
                                                 style="width:36px; height:36px; border-radius:50%; background-color:#7847D9 ; margin-right:10px"> | 
				
			|||
                                                <i class="fa fa-star  " | 
				
			|||
                                                   style="color:#fff; font-size:14px"></i> | 
				
			|||
                                            </div> | 
				
			|||
                                            <p style="color:#1A202C; font-weight:600; font-size:1.2rem; margin-bottom:2px"> | 
				
			|||
                                                Easily add, edit, and delete key-value pairs with a user-friendly UI. | 
				
			|||
                                            </p> | 
				
			|||
                                        </div> | 
				
			|||
                                    </div> | 
				
			|||
                                </div> | 
				
			|||
                                <div class="col-md-6 col-sm-12 p-3"> | 
				
			|||
                                    <div class="d-flex flex-column align-items-start h-100" | 
				
			|||
                                         style="padding:30px; border-radius:12px; background-color:#faf8ff"> | 
				
			|||
                                        <div class="d-flex align-items-center justify-content-center"> | 
				
			|||
                                            <div class="d-flex align-items-center justify-content-center " | 
				
			|||
                                                 style="width:36px; height:36px; border-radius:50%; background-color:#7847D9 ; margin-right:10px"> | 
				
			|||
                                                <i class="fa fa-star  " | 
				
			|||
                                                   style="color:#fff; font-size:14px"></i> | 
				
			|||
                                            </div> | 
				
			|||
                                            <p style="color:#1A202C; font-weight:600; font-size:1.2rem; margin-bottom:2px"> | 
				
			|||
                                                Ensures clean and consistent JSON data storage within your records. | 
				
			|||
                                            </p> | 
				
			|||
                                        </div> | 
				
			|||
 | 
				
			|||
                                    </div> | 
				
			|||
                                </div> | 
				
			|||
                                <div class="col-md-6 col-sm-12 p-3"> | 
				
			|||
                                    <div class="d-flex flex-column align-items-start h-100" | 
				
			|||
                                         style="padding:30px; border-radius:12px; background-color:#faf8ff"> | 
				
			|||
                                        <div class="d-flex align-items-center justify-content-center"> | 
				
			|||
                                            <div class="d-flex align-items-center justify-content-center " | 
				
			|||
                                                 style="width:36px; height:36px; border-radius:50%; background-color:#7847D9 ; margin-right:10px"> | 
				
			|||
                                                <i class="fa fa-star  " | 
				
			|||
                                                   style="color:#fff; font-size:14px"></i> | 
				
			|||
                                            </div> | 
				
			|||
                                            <p style="color:#1A202C; font-weight:600; font-size:1.2rem; margin-bottom:2px"> | 
				
			|||
                                                Works effortlessly with Odoo 17 models using JSON fields. | 
				
			|||
                                            </p> | 
				
			|||
                                        </div> | 
				
			|||
 | 
				
			|||
                                    </div> | 
				
			|||
                                </div> | 
				
			|||
                            </div> | 
				
			|||
                        </div> | 
				
			|||
                    </div> | 
				
			|||
                </div> | 
				
			|||
                <!--  --> | 
				
			|||
                <!-- related post --> | 
				
			|||
                <!--  --> | 
				
			|||
                <section class="oe_container mt32"> | 
				
			|||
                    <h2 style="color: #091E42;font-family: "Montserrat";text-align: center;margin: 25px auto;text-transform: uppercase;" | 
				
			|||
                        class="oe_slogan"> | 
				
			|||
                        <b>Related Products</b> | 
				
			|||
                    </h2> | 
				
			|||
                    <div id="demo" class="row carousel slide mt64 mb32" data-bs-ride="carousel"> | 
				
			|||
                        <!-- The slideshow --> | 
				
			|||
                        <div class="carousel-inner"> | 
				
			|||
                            <div class="carousel-item active"> | 
				
			|||
                                <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left; padding: 10px;"> | 
				
			|||
                                    <a href="https://apps.odoo.com/apps/modules/18.0/hide_menu_user" target="_blank" | 
				
			|||
                                       style="color: #000; text-decoration: none;"> | 
				
			|||
                                        <div style="border-radius: 6px; padding: 16px; border: 1px solid #cbcbcb;" | 
				
			|||
                                             class="shadow-sm"> | 
				
			|||
                                            <img class="img img-responsive center-block" style=" max-width: 100%;" | 
				
			|||
                                                 src="./assets/modules/b1.png"/> | 
				
			|||
                                            <h4 class="mt0 text-truncate" | 
				
			|||
                                                style="text-align:center;width:100% margin-bottom: 8px; font-weight: 600; padding-top: 16px; text-decoration:none;font-size: 18px; padding-bottom: 8px; margin-bottom: 0px"> | 
				
			|||
                                                Hide Any Menu User Wise</h4> | 
				
			|||
                                        </div> | 
				
			|||
                                    </a> | 
				
			|||
                                </div> | 
				
			|||
                                <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left; padding: 10px;"> | 
				
			|||
                                    <a href="https://apps.odoo.com/apps/modules/18.0/web_login_styles" target="_blank" | 
				
			|||
                                       style="color: #000; text-decoration: none;"> | 
				
			|||
                                        <div style="border-radius: 6px; padding: 16px; border: 1px solid #cbcbcb;" | 
				
			|||
                                             class="shadow-sm"> | 
				
			|||
                                            <img class="img img-responsive center-block" style=" max-width: 100%;" | 
				
			|||
                                                 src="./assets/modules/b2.png"/> | 
				
			|||
                                            <h4 class="mt0 text-truncate" | 
				
			|||
                                                style="text-align:center;width:100% margin-bottom: 8px; font-weight: 600; padding-top: 16px; text-decoration:none;font-size: 18px; padding-bottom: 8px; margin-bottom: 0px"> | 
				
			|||
                                                Customize Login Page Style</h4> | 
				
			|||
                                        </div> | 
				
			|||
                                    </a> | 
				
			|||
                                </div> | 
				
			|||
                                <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left; padding: 10px;"> | 
				
			|||
                                    <a href="https://apps.odoo.com/apps/modules/18.0/whatsapp_mail_messaging" | 
				
			|||
                                       target="_blank" style="color: #000; text-decoration: none;"> | 
				
			|||
                                        <div style="border-radius: 6px;padding: 16px; border: 1px solid #cbcbcb;" | 
				
			|||
                                             class="shadow-sm"> | 
				
			|||
                                            <img class="img img-responsive center-block" style=" max-width: 100%;" | 
				
			|||
                                                 src="./assets/modules/b3.png"/> | 
				
			|||
                                            <h4 class="mt0 text-truncate" | 
				
			|||
                                                style="text-align:center;width:100% margin-bottom: 8px; font-weight: 600; padding-top: 16px; text-decoration:none;font-size: 18px; padding-bottom: 8px; margin-bottom: 0px"> | 
				
			|||
                                                Odoo Whatsapp Connector</h4> | 
				
			|||
                                        </div> | 
				
			|||
                                    </a> | 
				
			|||
                                </div> | 
				
			|||
                            </div> | 
				
			|||
                            <div class="carousel-item"> | 
				
			|||
                                <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left; padding: 10px;"> | 
				
			|||
                                    <a href="https://apps.odoo.com/apps/modules/18.0/login_user_detail" target="_blank" | 
				
			|||
                                       style="color: #000; text-decoration: none;"> | 
				
			|||
                                        <div style="border-radius: 6px; padding: 16px; border: 1px solid #cbcbcb;" | 
				
			|||
                                             class="shadow-sm"> | 
				
			|||
                                            <img class="img img-responsive center-block" style=" max-width: 100%;" | 
				
			|||
                                                 src="./assets/modules/b4.png"/> | 
				
			|||
                                            <h4 class="mt0 text-truncate" | 
				
			|||
                                                style="text-align:center;width:100% margin-bottom: 8px; font-weight: 600; padding-top: 16px; text-decoration:none;font-size: 18px; padding-bottom: 8px; margin-bottom: 0px"> | 
				
			|||
                                                User Log Details</h4> | 
				
			|||
                                        </div> | 
				
			|||
                                    </a> | 
				
			|||
                                </div> | 
				
			|||
                                <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left; padding: 10px;"> | 
				
			|||
                                    <a href="https://apps.odoo.com/apps/modules/18.0/report_attachment_preview" | 
				
			|||
                                       target="_blank" style="color: #000; text-decoration: none;"> | 
				
			|||
                                        <div style="border-radius: 6px; padding: 16px; border: 1px solid #cbcbcb;" | 
				
			|||
                                             class="shadow-sm"> | 
				
			|||
                                            <img class="img img-responsive center-block" style=" max-width: 100%;" | 
				
			|||
                                                 src="./assets/modules/b5.png"/> | 
				
			|||
                                            <h4 class="mt0 text-truncate" | 
				
			|||
                                                style="text-align:center;width:100% margin-bottom: 8px; font-weight: 600; padding-top: 16px; text-decoration:none;font-size: 18px; padding-bottom: 8px; margin-bottom: 0px"> | 
				
			|||
                                                Reports and Attachments Preview in Browser</h4> | 
				
			|||
                                        </div> | 
				
			|||
                                    </a> | 
				
			|||
                                </div> | 
				
			|||
                                <div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left; padding: 10px;"> | 
				
			|||
                                    <a href="https://apps.odoo.com/apps/modules/18.0/project_dashboard_odoo" | 
				
			|||
                                       target="_blank" style="color: #000; text-decoration: none;"> | 
				
			|||
                                        <div style="border-radius: 6px; padding: 16px; border: 1px solid #cbcbcb;" | 
				
			|||
                                             class="shadow-sm"> | 
				
			|||
                                            <img class="img img-responsive center-block" style=" max-width: 100%;" | 
				
			|||
                                                 src="./assets/modules/b6.png"/> | 
				
			|||
                                            <h4 class="mt0 text-truncate" | 
				
			|||
                                                style="text-align:center;width:100% margin-bottom: 8px; font-weight: 600; padding-top: 16px; text-decoration:none;font-size: 18px; padding-bottom: 8px; margin-bottom: 0px"> | 
				
			|||
                                                Project Dashboard</h4> | 
				
			|||
                                        </div> | 
				
			|||
                                    </a> | 
				
			|||
                                </div> | 
				
			|||
                            </div> | 
				
			|||
                        </div> | 
				
			|||
                        <!-- Left and right controls --> | 
				
			|||
                        <a class="carousel-control-prev" href="#demo" data-bs-slide="prev" | 
				
			|||
                           style="margin-left: -30px;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="#demo" data-bs-slide="next" | 
				
			|||
                           style="margin-right: -30px;width: 35px;color: #000;"> | 
				
			|||
                        <span class="carousel-control-next-icon"> | 
				
			|||
        <i class="fa fa-chevron-right" style="font-size:24px"></i> | 
				
			|||
      </span> | 
				
			|||
                        </a> | 
				
			|||
                    </div> | 
				
			|||
                </section> | 
				
			|||
                <!-- service-section --> | 
				
			|||
 | 
				
			|||
                <section id="services" class="mt-5" style="border-radius: 16px; | 
				
			|||
                                                            border: 1px solid #EBEEF2; | 
				
			|||
                                                            background: var(--Neutral-N0, #FFF); | 
				
			|||
                                                            padding: 60px 40px; | 
				
			|||
                                                            box-shadow: 0px 5px 20px -11px rgba(0, 0, 0, 0.25);"> | 
				
			|||
                    <div class="text-center mt-4"><h3 class="mb-0" style="color: #000; | 
				
			|||
                                                                  text-align: center; | 
				
			|||
                                                                  font-family: Montserrat; | 
				
			|||
                                                                  font-size: 40px; | 
				
			|||
                                                                  font-style: normal; | 
				
			|||
                                                                  font-weight: 700; | 
				
			|||
                                                                  line-height: normal; | 
				
			|||
                                                                  text-transform: uppercase; | 
				
			|||
                                                                  padding-bottom: 50px;"> | 
				
			|||
                        Our Services</h3></div> | 
				
			|||
                    <div class="row mt-3"> | 
				
			|||
                        <div class="col-lg-3 col-sm-12 mb-3"> | 
				
			|||
                            <a href="#" style="text-decoration:none"> | 
				
			|||
                                <div class="btn-lg btn-block p-4 mb-2 d-flex flex-column justify-content-center align-items-center" | 
				
			|||
                                     style="font-size:25px; font-weight:bold;background-color:#FFE2E5; margin:auto; gap: 16px; border-radius: 8px;"> | 
				
			|||
                                    <div class="d-flex justify-content-center align-items-center" | 
				
			|||
                                         style="background-color:#FA5A7D; border-radius:50%; height:56px; width:56px"> | 
				
			|||
                                        <img src="./assets/icons/gear.svg" | 
				
			|||
                                             class="img-responsive" | 
				
			|||
                                             height="28px" width="28px"> | 
				
			|||
                                    </div> | 
				
			|||
                                    <span style="font-size: 18px; | 
				
			|||
                                  color: var(--text-color); | 
				
			|||
                                  font-weight: 600;"> Odoo Customization</span> | 
				
			|||
                                </div> | 
				
			|||
                            </a> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="col-lg-3 col-sm-12 mb-3"> | 
				
			|||
                            <a href="#" style="text-decoration:none"> | 
				
			|||
                                <div class="btn-lg btn-block p-4 mb-2 d-flex flex-column justify-content-center align-items-center" | 
				
			|||
                                     style="font-size:25px; font-weight:bold;background-color:#FFF4DE; margin:auto; gap: 16px; border-radius: 8px;"> | 
				
			|||
                                    <div class="d-flex justify-content-center align-items-center" | 
				
			|||
                                         style="background-color:#FF947A; border-radius:50%; height:56px; width:56px"> | 
				
			|||
                                        <img src="./assets/icons/wrench-icon.svg" | 
				
			|||
                                             class="img-responsive" | 
				
			|||
                                             height="28px" width="28px"> | 
				
			|||
                                    </div> | 
				
			|||
                                    <span style="font-size: 18px; | 
				
			|||
                    color: var(--text-color); | 
				
			|||
                    font-weight: 600;"> Odoo Implementation</span> | 
				
			|||
                                </div> | 
				
			|||
                            </a> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="col-lg-3 col-sm-12 mb-3"> | 
				
			|||
                            <a href="#" style="text-decoration:none"> | 
				
			|||
                                <div class="btn-lg btn-block p-4 mb-2 d-flex flex-column justify-content-center align-items-center" | 
				
			|||
                                     style="font-size:25px; font-weight:bold;background-color:#DCFCE7; margin:auto; gap: 16px; border-radius: 8px;"> | 
				
			|||
                                    <div class="d-flex justify-content-center align-items-center" | 
				
			|||
                                         style="background-color:#3CD856; border-radius:50%; height:56px; width:56px"> | 
				
			|||
                                        <img src="./assets/icons/life-ring-icon.svg" | 
				
			|||
                                             class="img-responsive" | 
				
			|||
                                             height="28px" width="28px"> | 
				
			|||
                                    </div> | 
				
			|||
                                    <span style="font-size: 18px; | 
				
			|||
                  color: var(--text-color); | 
				
			|||
                  font-weight: 600;">Odoo Support</span> | 
				
			|||
                                </div> | 
				
			|||
                            </a> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="col-lg-3 col-sm-12 mb-3"> | 
				
			|||
                            <a href="#" style="text-decoration:none"> | 
				
			|||
                                <div class="btn-lg btn-block p-4 mb-2 d-flex flex-column justify-content-center align-items-center" | 
				
			|||
                                     style="font-size:25px; font-weight:bold;background-color:#F3E8FF; margin:auto; gap: 16px; border-radius: 8px;"> | 
				
			|||
                                    <div class="d-flex justify-content-center align-items-center" | 
				
			|||
                                         style="background-color:#BF83FF; border-radius:50%; height:56px; width:56px"> | 
				
			|||
                                        <img src="./assets/icons/arrows-repeat.svg" | 
				
			|||
                                             class="img-responsive" | 
				
			|||
                                             height="28px" width="28px"> | 
				
			|||
                                    </div> | 
				
			|||
                                    <span style="font-size: 18px; | 
				
			|||
                color: var(--text-color); | 
				
			|||
                font-weight: 600;">Odoo Migration</span> | 
				
			|||
                                </div> | 
				
			|||
                            </a> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="col-lg-3 col-sm-12 mb-3"> | 
				
			|||
                            <a href="#" style="text-decoration:none"> | 
				
			|||
                                <div class="btn-lg btn-block p-4 mb-2 d-flex flex-column justify-content-center align-items-center" | 
				
			|||
                                     style="font-size:25px; font-weight:bold;background-color:#F1F9FF; margin:auto; gap: 16px; border-radius: 8px;"> | 
				
			|||
                                    <div class="d-flex justify-content-center align-items-center" | 
				
			|||
                                         style="background-color:#01649C; border-radius:50%; height:56px; width:56px"> | 
				
			|||
                                        <img src="./assets/icons/puzzle-piece-icon.svg" | 
				
			|||
                                             class="img-responsive" | 
				
			|||
                                             height="28px" width="28px"> | 
				
			|||
                                    </div> | 
				
			|||
                                    <span style="font-size: 18px; | 
				
			|||
              color: var(--text-color); | 
				
			|||
              font-weight: 600;">Odoo integration</span> | 
				
			|||
                                </div> | 
				
			|||
                            </a> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="col-lg-3 col-sm-12 mb-3"> | 
				
			|||
                            <a href="#" style="text-decoration:none"> | 
				
			|||
                                <div class="btn-lg btn-block p-4 mb-2 d-flex flex-column justify-content-center align-items-center" | 
				
			|||
                                     style="font-size:25px; font-weight:bold;background-color:#EDF8ED; margin:auto; gap: 16px; border-radius: 8px;"> | 
				
			|||
                                    <div class="d-flex justify-content-center align-items-center" | 
				
			|||
                                         style="background-color:#69CC70; border-radius:50%; height:56px; width:56px"> | 
				
			|||
                                        <img src="./assets/icons/odoo-consultancy.svg" | 
				
			|||
                                             class="img-responsive" | 
				
			|||
                                             height="28px" width="28px"> | 
				
			|||
                                    </div> | 
				
			|||
                                    <span style="font-size: 18px; | 
				
			|||
            color: var(--text-color); | 
				
			|||
            font-weight: 600;">Odoo Consultancy</span> | 
				
			|||
                                </div> | 
				
			|||
                            </a> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="col-lg-3 col-sm-12 mb-3"> | 
				
			|||
                            <a href="#" style="text-decoration:none"> | 
				
			|||
                                <div class="btn-lg btn-block p-4 mb-2 d-flex flex-column justify-content-center align-items-center" | 
				
			|||
                                     style="font-size:25px; font-weight:bold;background-color:#F1F6FF; margin:auto; gap: 16px; border-radius: 8px;"> | 
				
			|||
                                    <div class="d-flex justify-content-center align-items-center" | 
				
			|||
                                         style="background-color:#2E4556; border-radius:50%; height:56px; width:56px"> | 
				
			|||
                                        <img src="./assets/icons/odoo-licencing.svg" | 
				
			|||
                                             class="img-responsive" | 
				
			|||
                                             height="28px" width="28px"> | 
				
			|||
                                    </div> | 
				
			|||
                                    <span style="font-size: 18px; | 
				
			|||
          color: var(--text-color); | 
				
			|||
          font-weight: 600;">Odoo Licensing</span> | 
				
			|||
                                </div> | 
				
			|||
                            </a> | 
				
			|||
                        </div> | 
				
			|||
                        <div class="col-lg-3 col-sm-12 mb-3"> | 
				
			|||
                            <a href="#" style="text-decoration:none"> | 
				
			|||
                                <div class="btn-lg btn-block p-4 mb-2 d-flex flex-column justify-content-center align-items-center" | 
				
			|||
                                     style="font-size:25px; font-weight:bold;background-color:#FAF6EA; margin:auto; gap: 16px; border-radius: 8px;"> | 
				
			|||
 | 
				
			|||
                                    <div class="d-flex justify-content-center align-items-center" | 
				
			|||
                                         style="background-color:#FCD12C; border-radius:50%; height:56px; width:56px"> | 
				
			|||
                                        <img src="./assets/icons/hire-odoo.svg" | 
				
			|||
                                             class="img-responsive" | 
				
			|||
                                             height="28px" width="28px"> | 
				
			|||
                                    </div> | 
				
			|||
                                    <span style="font-size: 18px; | 
				
			|||
          color: var(--text-color); | 
				
			|||
          font-weight: 600;">Hire Odoo Developer</span> | 
				
			|||
                                </div> | 
				
			|||
                            </a> | 
				
			|||
                        </div> | 
				
			|||
                    </div></section></div> | 
				
			|||
            <!-- licence --> | 
				
			|||
            <div class="tab-pane fade" id="profile" role="tabpanel" | 
				
			|||
                 aria-labelledby="profile-tab"> | 
				
			|||
                <div class="px-5"> | 
				
			|||
                    .... | 
				
			|||
                </div> | 
				
			|||
            </div> | 
				
			|||
            <!--  --> | 
				
			|||
        </div> | 
				
			|||
        </section> | 
				
			|||
        <!--  --> | 
				
			|||
    </div> | 
				
			|||
</div> | 
				
			|||
</body> | 
				
			|||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"></script> | 
				
			|||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" | 
				
			|||
        integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" | 
				
			|||
        crossorigin="anonymous" referrerpolicy="no-referrer"></script> | 
				
			|||
<script src="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/owl.carousel.min.js"></script> | 
				
			|||
<script> | 
				
			|||
    $('.owl-carousel').owlCarousel({ | 
				
			|||
        rtl: true, | 
				
			|||
        loop: true, | 
				
			|||
        margin: 10, | 
				
			|||
        nav: true, | 
				
			|||
        responsive: { | 
				
			|||
            0: { | 
				
			|||
                items: 1 | 
				
			|||
            }, | 
				
			|||
            600: { | 
				
			|||
                items: 3 | 
				
			|||
            }, | 
				
			|||
            1000: { | 
				
			|||
                items: 3 | 
				
			|||
            } | 
				
			|||
        } | 
				
			|||
    }) | 
				
			|||
</script> | 
				
			|||
</html> | 
				
			|||
@ -0,0 +1,260 @@ | 
				
			|||
/** @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 } 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); | 
				
			|||
        }); | 
				
			|||
    } | 
				
			|||
    /** | 
				
			|||
     * 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); | 
				
			|||
@ -0,0 +1,96 @@ | 
				
			|||
<?xml version="1.0" encoding="UTF-8"?> | 
				
			|||
<templates xml:space="preserve"> | 
				
			|||
    <t t-name="web.JsonWidget"> | 
				
			|||
        <div class="o_field_json d-inline-flex flex-wrap w-100" | 
				
			|||
             t-att-class="{'o_tags_input o_input': !props.readonly}" | 
				
			|||
             t-ref="jsonWidget" | 
				
			|||
             t-on-keydown="onWidgetKeydown" | 
				
			|||
             t-on-click="openJsonEditor"> | 
				
			|||
            <TagsList tags="jsonSummaryTags()"/> | 
				
			|||
            <div class="o_input_dropdown d-inline-flex w-100" | 
				
			|||
                 t-att-class="{'cursor-pointer': !props.readonly}" | 
				
			|||
                 t-on-click="openJsonEditor"> | 
				
			|||
                <div class="d-flex align-items-center w-100 px-2"> | 
				
			|||
                    <t t-if="!state.entries.length"> | 
				
			|||
                        <span class="text-muted">Click to add data</span> | 
				
			|||
                    </t> | 
				
			|||
                </div> | 
				
			|||
                <t t-call="web.JsonWidgetPopup"/> | 
				
			|||
            </div> | 
				
			|||
        </div> | 
				
			|||
    </t> | 
				
			|||
    <t t-name="web.JsonWidgetPopup"> | 
				
			|||
        <div class="json_widget_popup dropdown-menu o-dropdown--menu show rounded py-0 overflow-hidden" | 
				
			|||
             style="width: 500px;overflow-y:scroll !important;" | 
				
			|||
             t-if="state.showDropdown" | 
				
			|||
             t-on-mounted="onDropdownMounted" | 
				
			|||
             t-ref="jsonDropdown"> | 
				
			|||
            <div class="popover-header sticky-top border-bottom"> | 
				
			|||
                <div class="d-flex align-items-center p-2"> | 
				
			|||
                    <div class="h5 mb-0 me-auto"> | 
				
			|||
                        JSON Data Editor | 
				
			|||
                    </div> | 
				
			|||
                    <button class="btn btn-link p-0" | 
				
			|||
                            t-on-click.stop="closeJsonEditor" | 
				
			|||
                            title="Close"> | 
				
			|||
                        <i class="fa fa-times"/> | 
				
			|||
                    </button> | 
				
			|||
                </div> | 
				
			|||
            </div> | 
				
			|||
            <div class="table-container p-2"> | 
				
			|||
                <div class="table-responsive"> | 
				
			|||
                    <table class="o_list_table table table-sm table-hover o_json_table mb-2 table-striped" | 
				
			|||
                           style="table-layout: fixed;"> | 
				
			|||
                        <colgroup> | 
				
			|||
                            <col style="width: 45%"/> | 
				
			|||
                            <col style="width: 45%"/> | 
				
			|||
                            <col style="width: 10%"/> | 
				
			|||
                        </colgroup> | 
				
			|||
                        <thead> | 
				
			|||
                            <tr> | 
				
			|||
                                <th class="border-bottom">Key</th> | 
				
			|||
                                <th class="border-bottom">Value</th> | 
				
			|||
                                <th class="border-bottom" aria-hidden="true"> | 
				
			|||
                                    <span class="d-none">Actions</span> | 
				
			|||
                                </th> | 
				
			|||
                            </tr> | 
				
			|||
                        </thead> | 
				
			|||
                        <tbody> | 
				
			|||
                            <tr t-foreach="state.entries" | 
				
			|||
                                t-as="entry" | 
				
			|||
                                t-key="entry.id"> | 
				
			|||
                                <Record t-props="recordProps(entry)" | 
				
			|||
                                        t-slot-scope="scope"> | 
				
			|||
                                    <td class="align-middle text-truncate entry-key"> | 
				
			|||
                                        <Field name="'key'" | 
				
			|||
                                               record="scope.record"/> | 
				
			|||
                                    </td> | 
				
			|||
                                    <td class="align-middle text-truncate"> | 
				
			|||
                                        <Field name="'value'" | 
				
			|||
                                               record="scope.record"/> | 
				
			|||
                                    </td> | 
				
			|||
                                    <td class="align-middle text-center"> | 
				
			|||
                                        <button class="btn btn-link text-danger p-0" | 
				
			|||
                                                t-on-click.stop="() => this.deleteLine(entry.index)" | 
				
			|||
                                                title="Delete"> | 
				
			|||
                                            <i class="fa fa-trash-o"/> | 
				
			|||
                                        </button> | 
				
			|||
                                    </td> | 
				
			|||
                                </Record> | 
				
			|||
                            </tr> | 
				
			|||
                            <tr t-if="!props.readonly"> | 
				
			|||
                                <td colspan="3"> | 
				
			|||
                                    <button class="btn btn-link p-0" | 
				
			|||
                                            t-on-click.stop="() => this.addLine()" | 
				
			|||
                                            t-ref="addLineButton"> | 
				
			|||
                                        Add a Line | 
				
			|||
                                    </button> | 
				
			|||
                                </td> | 
				
			|||
                            </tr> | 
				
			|||
                        </tbody> | 
				
			|||
                    </table> | 
				
			|||
                </div> | 
				
			|||
            </div> | 
				
			|||
        </div> | 
				
			|||
    </t> | 
				
			|||
</templates> | 
				
			|||