This commit is contained in:
pengyuthon
2024-06-14 16:24:02 +08:00
parent e62d4a7382
commit d6cf1ff349
50 changed files with 2529 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
from . import controller
@@ -0,0 +1,65 @@
{
"name": "Clarity Backend Theme for community",
"version": "17.0.1.0.1",
'author': "Terabits Technolab",
'summary': """
Clarity backend theme
Odoo Backend Theme, Odoo Community Backend Theme, Web backend Theme, Web Responsive Odoo Theme, New theme design, New design, Multi Level Menu,
Web Responsive , Odoo Theme, Odoo Modern Theme, Odoo Modern Backend Theme Odoo, Advance Theme Backend Advanced, Left sidebar menu,
All in one, New advanced Odoo Menu, Sidebar apps, Web menu, Odoo backend menu, Web Responsive menu, Sidebar dark,
Advance Menu Odoo App Menu Apps, Advanced Apps Menu, Elegant Menu, Web App Menu Backend, Menu Odoo Backend, Collapse Menu, Light Sidebar,
Expand Menu, Collapsed Menu, Expanded Menu, New Style Menus, Advanced Sidebar Menu, Advance Sidebar Menu, Responsive Menu Sidebar, Sidebar Theme,
Responsive Sidebar, Hide menu, Show Menu, Hide Sidebar, Show Sidebar, Toggle Menu, Toggle Sidebar, Menu Theme,
Quick Backend Menu, Dropdown Menu, Parent Menus, Shortcut Menus, Menu Icons, Collapsible menu Odoo,
Menu Dynamic Sidebar, Advanced Menu, Backend Odoo Web, Elegant Theme Simple, Advance List View Manager,
Arc Backend Theme, Fully Functional Theme, Flexible Backend Theme, Fast Backend Theme, Advance Material Backend Theme, Customizable Backend Theme,
Attractive Theme for Backend, Elegant Backend Theme, Responsive Web Client, Backend UI, Mobile Responsive for Odoo Community,
Flexible Enterprise Theme, Enterprise Backend Theme
""",
'description': """
Clarity backend theme
Odoo Backend Theme, Odoo Community Backend Theme, Web backend Theme, Web Responsive Odoo Theme, New theme design, New design, Multi Level Menu,
Web Responsive , Odoo Theme, Odoo Modern Theme, Odoo Modern Backend Theme Odoo, Advance Theme Backend Advanced, Left sidebar menu,
All in one, New advanced Odoo Menu, Sidebar apps, Web menu, Odoo backend menu, Web Responsive menu, Sidebar dark,
Advance Menu Odoo App Menu Apps, Advanced Apps Menu, Elegant Menu, Web App Menu Backend, Menu Odoo Backend, Collapse Menu, Light Sidebar,
Expand Menu, Collapsed Menu, Expanded Menu, New Style Menus, Advanced Sidebar Menu, Advance Sidebar Menu, Responsive Menu Sidebar, Sidebar Theme,
Responsive Sidebar, Hide menu, Show Menu, Hide Sidebar, Show Sidebar, Toggle Menu, Toggle Sidebar, Menu Theme,
Quick Backend Menu, Dropdown Menu, Parent Menus, Shortcut Menus, Menu Icons, Collapsible menu Odoo,
Menu Dynamic Sidebar, Advanced Menu, Backend Odoo Web, Elegant Theme Simple, Advance List View Manager,
Arc Backend Theme, Fully Functional Theme, Flexible Backend Theme, Fast Backend Theme, Advance Material Backend Theme, Customizable Backend Theme,
Attractive Theme for Backend, Elegant Backend Theme, Responsive Web Client, Backend UI, Mobile Responsive for Odoo Community,
Flexible Enterprise Theme, Enterprise Backend Theme
""",
"sequence": 7,
"license": "OPL-1",
"category": "Themes/Backend",
"website": "https://www.terabits.xyz",
"depends": ["web"],
"data": [
'views/res_config_setting.xml',
'views/res_users.xml',
'views/webclient_templates.xml'
],
"assets": {
"web.assets_frontend": [
'clarity_backend_theme_bits/static/src/scss/login.scss'
],
"web.assets_backend": [
'clarity_backend_theme_bits/static/src/xml/WebClient.xml',
'clarity_backend_theme_bits/static/src/xml/navbar/sidebar.xml',
'clarity_backend_theme_bits/static/src/xml/systray_items/user_menu.xml',
'clarity_backend_theme_bits/static/src/js/SidebarBottom.js',
'clarity_backend_theme_bits/static/src/js/WebClient.js',
'clarity_backend_theme_bits/static/src/scss/layout.scss',
'clarity_backend_theme_bits/static/src/scss/navbar.scss',
'clarity_backend_theme_bits/static/src/js/navbar.js',
],
},
'installable': True,
'application': True,
'auto_install': False,
'images': [
'static/description/logo.gif',
'static/description/theme_screenshot.gif',
],
}
@@ -0,0 +1 @@
from . import main
@@ -0,0 +1,17 @@
import datetime
import pytz
from odoo import http, models, fields, api, tools
from odoo.http import request
class BackThemeBits(http.Controller):
@http.route(['/get/menu_data'], type='json', auth='public')
def get_irmenu_icondata(self, **kw):
menuobj = request.env['ir.ui.menu']
menu_recs = request.env['ir.ui.menu'].sudo().search(
[('id', 'in', kw.get('menu_ids'))])
app_menu_dict = {}
for menu in menu_recs:
menu_dict = menu.read(set(menuobj._fields))
app_menu_dict[menu.id] = menu_dict
return app_menu_dict
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 KiB

@@ -0,0 +1,676 @@
<!DOCTYPE html>
<html lang="en-US" data-website-id="1" data-oe-company-name="Odoo S.A.">
<head>
<link type="text/css" rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" />
<script src="https://code.jquery.com/jquery-3.6.0.js"
integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css2?family=Halant:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
<link type="text/css" rel="stylesheet" href="/assets/assets.css" />
</head>
<body>
<div id="module-description">
<!-- Keep From Here -->
<div class="container">
<div class="oe_styling_v8">
<img class="img img-responsive center-block" style="border-top-left-radius:10px; border-top-right-radius:10px" src="https://www.terabits.xyz/index/img/clarity_backend_theme_bits/17.0/img.png">
<!-- blog post starts -->
<section class="blog_post_01">
<div class="position-relative w-100" style="display: inline-grid;">
<img src="images/blog_post_bg_01.png" class="img-responsive w-100 h-100 img img-fluid position-absolute left_0"/>
<div class="position-relative row justify-content-center align-items-center" style="padding: 20px 10px 20px 10px;">
<div class="col-12 my-3 px-5">
<div class="header-img">
<img src="images/blogpost_header_img.png" class="img img-fluid w-100" style="width: 100% !important;"/>
</div>
<div class="blg-01-content text-center" style="margin-top: 65px;">
<h1 style="font-family: 'Inter', sans-serif; font-size: 55px; font-weight: 700;line-height: 61px;color: #151765;margin-bottom: 0 !important;">
Clarity Backend Theme
</h1>
<h1 style="font-family: 'Inter', sans-serif; font-size: 28px; font-weight: 600;line-height: 41px;color: #4267C8;">
Odoo community backend theme
</h1>
<p style="font-family: 'Inter', sans-serif; font-size: 18px; font-weight: 500;line-height: 27px; color: #000000; margin-top: 20px;">
The clarity backend theme have amazing appearance on any device and is easy to <br/>
switch between all screen sizes. Clicking on any menu is made simple with an <br/>
contemporary and modern sidebar. You can browse across different apps using <br/>
elegant sidebar menu.The theme is designed, keeping in mind the delivery of <br/>
great user experience and user-friendly interface to your users.
</p>
</div>
<div class="features px-5 mx-5" style="margin-top: 70px;">
<div class="row justify-content-center">
<div class="col-xl-6 d-flex justify-content-end my-1">
<div class="box" style="background-color: #151765; border-radius: 10px; padding: 10px 20px; width: 420px;">
<h4 style="font-family: 'Inter', sans-serif; font-size: 18px; font-weight: 500;line-height: 27px;color: #fff;margin-bottom: 0 !important;">
App Drawer design for Community Addition
</h4>
</div>
</div>
<div class="col-xl-6 d-flex justify-content-start my-1">
<div class="box" style="background-color: #151765; border-radius: 10px; padding: 10px 20px; width: 420px;">
<h4 style="font-family: 'Inter', sans-serif; font-size: 18px; font-weight: 500;line-height: 27px;color: #fff;margin-bottom: 0 !important;">
Login & Signup Redesign
</h4>
</div>
</div>
<div class="col-xl-6 d-flex justify-content-end my-1">
<div class="box" style="background-color: #151765; border-radius: 10px; padding: 10px 20px; width: 420px;">
<h4 style="font-family: 'Inter', sans-serif; font-size: 18px; font-weight: 500;line-height: 27px;color: #fff;margin-bottom: 0 !important;">
Customized Discuss view design
</h4>
</div>
</div>
<div class="col-xl-6 d-flex justify-content-start my-1">
<div class="box" style="background-color: #151765; border-radius: 10px; padding: 10px 20px; width: 420px;">
<h4 style="font-family: 'Inter', sans-serif; font-size: 18px; font-weight: 500;line-height: 27px;color: #fff;margin-bottom: 0 !important;">
Show brand's logo in menu
</h4>
</div>
</div>
<div class="col-xl-6 d-flex justify-content-end my-1">
<div class="box" style="background-color: #151765; border-radius: 10px; padding: 10px 20px; width: 420px;">
<h4 style="font-family: 'Inter', sans-serif; font-size: 18px; font-weight: 500;line-height: 27px;color: #fff;margin-bottom: 0 !important;">
Customzed List, Form, Kanban view design
</h4>
</div>
</div>
<div class="col-xl-6 d-flex justify-content-start my-1">
<div class="box" style="background-color: #151765; border-radius: 10px; padding: 10px 20px; width: 420px;">
<h4 style="font-family: 'Inter', sans-serif; font-size: 18px; font-weight: 500;line-height: 27px;color: #fff;margin-bottom: 0 !important;">
Responsive sidebar design
</h4>
</div>
</div>
</div>
</div>
<div class="before_after_img px-5 pb-3" style="margin-top: 70px;">
<img src="images/main-b.png" class="img img-fluid w-100" style="width: 100% !important;"/>
</div>
</div>
</div>
</div>
</section>
<!-- blog post ends -->
<!-- features highlight -->
<section class="blog_post_01">
<div class="position-relative w-100" style="display: inline-grid;">
<img src="images/blog_ss_bg_03.png" class="img-responsive w-100 h-100 img img-fluid position-absolute left_0"/>
<div class="position-relative row justify-content-center align-items-center" style="padding: 40px 20px 40px 20px;">
<div class="col-12 my-3 px-5">
<div class="mt-2">
<div class="content-note d-flex ">
<div class="icon-img">
<img src="images/icon_img.png" class="img img-fluid"/>
</div>
<div class="content" style="margin-left: 15px !important;">
<p style="font-family: 'Inter', sans-serif; font-size: 25px; font-weight: 600;line-height: 26px;color: #151765;">
Custom discuss view
</p>
</div>
</div>
<div class="content-img text-center mt-3 mx-5">
<img src="images/1.png" class="img img-fluid img-responsive"/>
</div>
</div>
<div class="mt-5">
<div class="content-note d-flex ">
<div class="icon-img">
<img src="images/icon_img.png" class="img img-fluid"/>
</div>
<div class="content" style="margin-left: 15px !important;">
<p style="font-family: 'Inter', sans-serif; font-size: 25px; font-weight: 600;line-height: 26px;color: #151765;">
Interactive and clean design
</p>
</div>
</div>
<div class="content-img text-center mt-3 mx-5">
<img src="images/2.png" class="img img-fluid img-responsive"/>
</div>
</div>
<div class="mt-5">
<div class="content-note d-flex ">
<div class="icon-img">
<img src="images/icon_img.png" class="img img-fluid"/>
</div>
<div class="content" style="margin-left: 15px !important;">
<p style="font-family: 'Inter', sans-serif; font-size: 25px; font-weight: 600;line-height: 26px;color: #151765;">
Custom list view design
</p>
</div>
</div>
<div class="content-img text-center mt-3 mx-5">
<img src="images/3.png" class="img img-fluid img-responsive"/>
</div>
</div>
<div class="mt-5">
<div class="content-note d-flex ">
<div class="icon-img">
<img src="images/icon_img.png" class="img img-fluid"/>
</div>
<div class="content" style="margin-left: 15px !important;">
<p style="font-family: 'Inter', sans-serif; font-size: 25px; font-weight: 600;line-height: 26px;color: #151765;">
Custom kanban view design
</p>
</div>
</div>
<div class="content-img text-center mt-3 mx-5">
<img src="images/4.png" class="img img-fluid img-responsive"/>
</div>
</div>
<div class="mt-5">
<div class="content-note d-flex ">
<div class="icon-img">
<img src="images/icon_img.png" class="img img-fluid"/>
</div>
<div class="content" style="margin-left: 15px !important;">
<p style="font-family: 'Inter', sans-serif; font-size: 25px; font-weight: 600;line-height: 26px;color: #151765;">
Custom form view design
</p>
</div>
</div>
<div class="content-img text-center mt-3 mx-5">
<img src="images/5.png" class="img img-fluid img-responsive"/>
</div>
</div>
<div class="mt-5">
<div class="content-note d-flex ">
<div class="icon-img">
<img src="images/icon_img.png" class="img img-fluid"/>
</div>
<div class="content" style="margin-left: 15px !important;">
<p style="font-family: 'Inter', sans-serif; font-size: 25px; font-weight: 600;line-height: 26px;color: #151765;">
Custom sign up design
</p>
<h6 class="text-danger font-size-xl"><b>(The login/signup design will appear only the backend login/signup view.
It will not appear in the website login/signup view.)</b>
</h6>
</div>
</div>
<div class="content-img text-center mt-3 mx-5">
<img src="images/6.png" class="img img-fluid img-responsive"/>
</div>
</div>
<div class="mt-5">
<div class="content-note d-flex ">
<div class="icon-img">
<img src="images/icon_img.png" class="img img-fluid"/>
</div>
<div class="content" style="margin-left: 15px !important;">
<p style="font-family: 'Inter', sans-serif; font-size: 25px; font-weight: 600;line-height: 26px;color: #151765;">
Custom login design
</p>
</div>
</div>
<div class="content-img text-center mt-3 mx-5">
<img src="images/7.png" class="img img-fluid img-responsive"/>
</div>
</div>
<div class="mt-5">
<div class="content-note d-flex ">
<div class="icon-img">
<img src="images/icon_img.png" class="img img-fluid"/>
</div>
<div class="content" style="margin-left: 15px !important;">
<p style="font-family: 'Inter', sans-serif; font-size: 25px; font-weight: 600;line-height: 26px;color: #151765;">
Custom reset form design
</p>
</div>
</div>
<div class="content-img text-center mt-3 mx-5">
<img src="images/8.png" class="img img-fluid img-responsive"/>
</div>
</div>
<div class="mt-5">
<div class="content-note d-flex ">
<div class="icon-img">
<img src="images/icon_img.png" class="img img-fluid"/>
</div>
<div class="content" style="margin-left: 15px !important;">
<p style="font-family: 'Inter', sans-serif; font-size: 25px; font-weight: 600;line-height: 26px;color: #151765;">
Set company logo
</p>
</div>
</div>
<div class="content-img text-center mt-3 mx-5">
<img src="images/9.png" class="img img-fluid img-responsive"/>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- features highlight -->
<!-- simplify_banner -->
<section class="dashboard_01">
<h1 style="font-family: 'Inter', sans-serif;font-size: 40px;font-weight: 700;line-height: 45px;color: #151765;text-align: center;margin: 40px 0;">
Suggested Apps
</h1>
<div class="position-relative" style="display: inline-grid;">
<img src="images/simplify_banner_bg.png"
class="w-100 h-100 position-absolute left_0 img img-fluid" />
<div class="position-relative col-12 my-3" style="padding: 40px;">
<div class="row align-items-center">
<div class="col-xl-6">
<h2
style="font-family: 'Inter', sans-serif; font-size: 30px;font-weight: 700;line-height: 69px;color: #151756;">
Simplify access management</h2>
<p
style="font-family: 'Inter', sans-serif; font-size: 18px;font-weight: 500;line-height: 29px;color: #151756;">
"Simplify Access Management can Control permissions for all aspects of your
Odoo
system easily from one place. Save up to 80% of customization time!"
</p>
<div class="d-flex mt-4">
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Hide menu/sub menu</span>
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Models access rights</span>
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Fields access right</span>
</div>
<div class="d-flex">
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Buttons/tab access rights</span>
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Disable developer mode</span>
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Hide chatter</span>
</div>
<div class="d-flex">
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Domain access right</span>
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Hide filter and groups</span>
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Readonly users</span>
</div>
<div class="text-center mt-4">
<a href="https://apps.odoo.com/apps/modules/17.0/simplify_access_management/"
style="text-decoration: none; background-color: #151765;font-size: 16px;font-family: 'Inter',sans-serif; font-weight: 500; color: #fff;padding: 10px 15px;
line-height: 24px;border-radius: 5px;">
Live demo available
</a>
</div>
</div>
<div class="col-xl-6">
<img src="images/banner.png" class="img w-100 img-fluid" />
<div class="text-center mt-5">
<a href="https://apps.odoo.com/apps/modules/browse?author=Terabits%20Technolab"
style="text-decoration: none; border: 2px solid #151756 ;font-size: 16px; font-weight: 600; font-family: 'Inter',sans-serif;color: #151765;padding: 8px 15px;
line-height: 24px;border-radius: 5px;">
View more
</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- simplify_banner -->
<!-- clarity_pro_banner -->
<section class="dashboard_01 my-2">
<div class="position-relative" style="display: inline-grid;">
<img src="images/simplify_banner_bg.png"
class="w-100 h-100 position-absolute left_0 img img-fluid" />
<div class="position-relative row align-items-center justify-content-between col-12 " style="padding: 40px 10px 50px 50px">
<div class="row align-items-center mb-4">
<div class="col-xl-6">
<h2
style="font-family: 'Inter', sans-serif; font-size: 40px;font-weight: 700;line-height: 69px;color: #151756;">
Clarity Pro Backend Theme</h2>
<p
style="font-family: 'Inter', sans-serif; font-size: 18px;font-weight: 500;line-height: 29px;color: #151756;">
The clarity backend theme have amazing appearance on any device and is easy to switch between all screen sizes.
The theme is designed, keeping in mind the delivery of great user experience and user-friendly interface to your users.
</p>
<div class="d-flex mt-4">
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Main menu for community</span>
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Sidebar menu/top menu</span>
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Multi tabs management</span>
</div>
<div class="d-flex">
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 12px;font-weight: 500;line-height: 25px;color: #151756;">
Global search</span>
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 12px;font-weight: 500;line-height: 25px;color: #151756;">
Global search in record</span>
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 12px;font-weight: 500;line-height: 25px;color: #151756;">
Global search in menu</span>
</div>
<div class="d-flex">
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Multi font style</span>
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Multi icon style</span>
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Custom color schemes</span>
</div>
<div class="d-flex">
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Full-screen switch</span>
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Bookmark management</span>
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Attractive dark mode</span>
</div>
<div class="d-flex">
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Kanban & list view style</span>
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Checkbox & radio style</span>
<span class="w-100"
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
RTL support</span>
</div>
<div class="text-center mt-4">
<a href="https://apps.odoo.com/apps/themes/17.0/clarity_backend_theme_pro_bits/"
style="text-decoration: none; background-color: #151765;font-size: 16px;font-family: 'Inter',sans-serif; font-weight: 500; color: #fff;padding: 10px 15px;
line-height: 24px;border-radius: 5px;">
Live demo available
</a>
</div>
</div>
<div class="col-xl-6 mt-5">
<img src="images/clarity_pro_banner.png" class="img img-fluid" />
<div class="text-center mt-5">
<a href="https://apps.odoo.com/apps/modules/browse?author=Terabits%20Technolab"
style="text-decoration: none; border: 2px solid #151756 ;font-size: 16px; font-weight: 600; font-family: 'Inter',sans-serif;color: #151765;padding: 8px 15px;
line-height: 24px;border-radius: 5px;">
View more
</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- clarity_pro_banner -->
<!-- simplify_banner -->
<section class="dashboard_01 my-2">
<div class="position-relative" style="display: inline-grid;">
<img src="images/simplify_banner_bg.png"
class="w-100 h-100 position-absolute left_0 img img-fluid" />
<div class="position-relative row align-items-center justify-content-between col-12 " style="padding: 40px 10px 40px 50px">
<div class="row align-items-center">
<div class="col-xl-6">
<h2
style="font-family: 'Inter', sans-serif; font-size: 40px;font-weight: 700;line-height: 69px;color: #151756;">
AnalytiX Dashboard</h2>
<p
style="font-family: 'Inter', sans-serif; font-size: 18px;font-weight: 500;line-height: 29px;color: #151756;">
"Unlock the true potential of your data with AnalytiX Dashboard, a cutting-edge Odoo
dashboard module designed to revolutionizethe way you visualize & analyze information."
</p>
<div class="d-flex mt-4">
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Predefined date filter</span>
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Real-time Analytics</span>
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Customizable Dashboards</span>
</div>
<div class="d-flex">
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 12px;font-weight: 500;line-height: 25px;color: #151756;">
Smart Data Visualization</span>
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 12px;font-weight: 500;line-height: 25px;color: #151756;">
User-Friendly Interface</span>
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 12px;font-weight: 500;line-height: 25px;color: #151756;">
Import/Export dashboard</span>
</div>
<div class="d-flex">
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Group access control</span>
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Share your findings</span>
<span
style="background-color: #fff; padding: 5px 10px; border-radius: 20px; margin: 6px 4px;
font-family: 'Inter', sans-serif; font-size: 13px;font-weight: 500;line-height: 25px;color: #151756;">
Fully responsive layout</span>
</div>
<div class="text-center mt-4">
<a href="https://apps.odoo.com/apps/modules/17.0/analytix_dashboard_bits/"
style="text-decoration: none; background-color: #151765;font-size: 16px;font-family: 'Inter',sans-serif; font-weight: 500; color: #fff;padding: 10px 15px;
line-height: 24px;border-radius: 5px;">
Live demo available
</a>
</div>
</div>
<div class="col-xl-6 mt-5">
<img src="images/analytix_banner.png" class="img img-fluid" />
<div class="text-center mt-5">
<a href="https://apps.odoo.com/apps/modules/browse?author=Terabits%20Technolab"
style="text-decoration: none; border: 2px solid #151756 ;font-size: 16px; font-weight: 600; font-family: 'Inter',sans-serif;color: #151765;padding: 8px 15px;
line-height: 24px;border-radius: 5px;">
View more
</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- simplify_banner -->
<!-- Help START -->
<div class="row pb16 pt48 mb-5">
<div class="alert alert-warning text-center w-100" style="
padding: 21px 51px;
background-color: #ffffff;
border: 1px solid #dee2e6;
color: #414d5c;
margin: auto;
display: block;
border-radius: 1px;
min-width: 90%;
border-top: 3px solid #E5202B;
">
<div>
<div style="
background-color: rgb(255 164 0 / 12%);
color: #E5202B;
" class="badge border-0 rounded-circle p-3">
<i class="fa fa-question-circle fa-2x"></i>
</div>
</div>
<h2 style="color: #3c4858" class="mt-2 mb-4">
Need a help for this module?
</h2>
<h4 style="color: #3c4858; font-weight: 400" class="mt-2 mb-4">
Contact me
<b style="
color: #25282D;
background-color: #e0f0ff;
padding: 3px 10px;
border-radius: 3px;
">info@terabits.xyz</b>
for your queries
</h4>
</div>
</div>
<!-- Help END -->
</div>
</div>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

@@ -0,0 +1,193 @@
/** @odoo-module **/
import { Dropdown } from "@web/core/dropdown/dropdown";
import { useService } from "@web/core/utils/hooks";
import { registry } from "@web/core/registry";
import { debounce } from "@web/core/utils/timing";
import { ErrorHandler } from "@web/core/utils/components";
import { NavBarDropdownItem,MenuDropdown } from '@web/static/src/webclient/navbar/navbar';
import {
Component,
onWillDestroy,
useExternalListener,
useEffect,
useRef,
onWillUnmount,
} from "@odoo/owl";
const systrayRegistry = registry.category("systray");
const getBoundingClientRect = Element.prototype.getBoundingClientRect;
export class HeaderBar extends NavBar {
setup() {
this.currentAppSectionsExtra = [];
this.actionService = useService("action");
this.menuService = useService("menu");
this.root = useRef("root");
this.appSubMenus = useRef("appSubMenus");
const debouncedAdapt = debounce(this.adapt.bind(this), 250);
onWillDestroy(() => debouncedAdapt.cancel());
useExternalListener(window, "resize", debouncedAdapt);
let adaptCounter = 0;
const renderAndAdapt = () => {
adaptCounter++;
this.render();
};
systrayRegistry.addEventListener("UPDATE", renderAndAdapt);
this.env.bus.addEventListener("MENUS:APP-CHANGED", renderAndAdapt);
onWillUnmount(() => {
systrayRegistry.removeEventListener("UPDATE", renderAndAdapt);
this.env.bus.removeEventListener("MENUS:APP-CHANGED", renderAndAdapt);
});
// We don't want to adapt every time we are patched
// rather, we adapt only when menus or systrays have changed.
useEffect(
() => {
this.adapt();
},
() => [adaptCounter]
);
}
handleItemError(error, item) {
// remove the faulty component
item.isDisplayed = () => false;
Promise.resolve().then(() => {
throw error;
});
}
get currentApp() {
return this.menuService.getCurrentApp();
}
get currentAppSections() {
return (
(this.currentApp && this.menuService.getMenuAsTree(this.currentApp.id).childrenTree) ||
[]
);
}
// This dummy setter is only here to prevent conflicts between the
// Enterprise NavBar extension and the Website NavBar patch.
set currentAppSections(_) {}
get systrayItems() {
return systrayRegistry
.getEntries()
.map(([key, value]) => ({ key, ...value }))
.filter((item) => ("isDisplayed" in item ? item.isDisplayed(this.env) : true))
.reverse();
}
// This dummy setter is only here to prevent conflicts between the
// Enterprise NavBar extension and the Website NavBar patch.
set systrayItems(_) {}
/**
* Adapt will check the available width for the app sections to get displayed.
* If not enough space is available, it will replace by a "more" menu
* the least amount of app sections needed trying to fit the width.
*
* NB: To compute the widths of the actual app sections, a render needs to be done upfront.
* By the end of this method another render may occur depending on the adaptation result.
*/
async adapt() {
if (!this.root.el) {
/** @todo do we still need this check? */
// currently, the promise returned by 'render' is resolved at the end of
// the rendering even if the component has been destroyed meanwhile, so we
// may get here and have this.el unset
return;
}
// ------- Initialize -------
// Get the sectionsMenu
const sectionsMenu = this.appSubMenus.el;
if (!sectionsMenu) {
// No need to continue adaptations if there is no sections menu.
return;
}
// Save initial state to further check if new render has to be done.
const initialAppSectionsExtra = this.currentAppSectionsExtra;
const firstInitialAppSectionExtra = [...initialAppSectionsExtra].shift();
const initialAppId = firstInitialAppSectionExtra && firstInitialAppSectionExtra.appID;
// Restore (needed to get offset widths)
const sections = [
...sectionsMenu.querySelectorAll(":scope > *:not(.o_menu_sections_more)"),
];
for (const section of sections) {
section.classList.remove("d-none");
}
this.currentAppSectionsExtra = [];
// ------- Check overflowing sections -------
// use getBoundingClientRect to get unrounded values for width in order to avoid rounding problem
// with offsetWidth.
const sectionsAvailableWidth = getBoundingClientRect.call(sectionsMenu).width;
const sectionsTotalWidth = sections.reduce(
(sum, s) => sum + getBoundingClientRect.call(s).width,
0
);
if (sectionsAvailableWidth < sectionsTotalWidth) {
// Sections are overflowing
// Initial width is harcoded to the width the more menu dropdown will take
let width = 46;
for (const section of sections) {
if (sectionsAvailableWidth < width + section.offsetWidth) {
// Last sections are overflowing
const overflowingSections = sections.slice(sections.indexOf(section));
overflowingSections.forEach((s) => {
// Hide from normal menu
s.classList.add("d-none");
// Show inside "more" menu
const sectionId =
s.dataset.section ||
s.querySelector("[data-section]").getAttribute("data-section");
const currentAppSection = this.currentAppSections.find(
(appSection) => appSection.id.toString() === sectionId
);
this.currentAppSectionsExtra.push(currentAppSection);
});
break;
}
width += section.offsetWidth;
}
}
// ------- Final rendering -------
const firstCurrentAppSectionExtra = [...this.currentAppSectionsExtra].shift();
const currentAppId = firstCurrentAppSectionExtra && firstCurrentAppSectionExtra.appID;
if (
initialAppSectionsExtra.length === this.currentAppSectionsExtra.length &&
initialAppId === currentAppId
) {
// Do not render if more menu items stayed the same.
return;
}
return this.render();
}
onNavBarDropdownItemSelection(menu) {
if (menu) {
this.menuService.selectMenu(menu);
}
}
getMenuItemHref(payload) {
const parts = [`menu_id=${payload.id}`];
if (payload.actionID) {
parts.push(`action=${payload.actionID}`);
}
return "#" + parts.join("&");
}
}
HeaderBar.template = "web.NavBar";
HeaderBar.components = { Dropdown, NavBarDropdownItem, MenuDropdown, ErrorHandler };
HeaderBar.props = {};
@@ -0,0 +1,36 @@
/** @odoo-module **/
import { Dropdown } from "@web/core/dropdown/dropdown";
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
import { CheckBox } from "@web/core/checkbox/checkbox";
import { browser } from "@web/core/browser/browser";
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
import { Component } from "@odoo/owl";
const userMenuRegistry = registry.category("user_menuitems");
export class SidebarBottom extends Component {
setup() {
this.user = useService("user");
const { origin } = browser.location;
const { userId } = this.user;
this.source = `${origin}/web/image?model=res.users&field=avatar_128&id=${userId}`;
}
getElements() {
const sortedItems = userMenuRegistry
.getAll()
.map((element) => element(this.env))
.sort((x, y) => {
const xSeq = x.sequence ? x.sequence : 100;
const ySeq = y.sequence ? y.sequence : 100;
return xSeq - ySeq;
});
return sortedItems;
}
}
SidebarBottom.template = "SidebarBottom";
SidebarBottom.components = { Dropdown, DropdownItem, CheckBox };
SidebarBottom.props = {};
@@ -0,0 +1,89 @@
/** @odoo-module **/
import { useService, useState} from "@web/core/utils/hooks";
import { WebClient } from "@web/webclient/webclient";
import { patch } from "@web/core/utils/patch";
import { useRef } from "@odoo/owl";
import { SidebarBottom } from "./SidebarBottom";
patch(WebClient.prototype, {
setup() {
super.setup();
this.root = useRef("root");
this.rpc = useService('rpc');
this.companyService = useService("company");
this.menuService = useService("menu");
this.currentCompany = this.companyService.currentCompany;
this.fetch_menu_data();
},
toggleSidebar(ev){
$(ev.currentTarget).toggleClass('visible');
$('.nav-wrapper-bits').toggleClass('toggle-show');
},
fetch_menu_data(){
var menu_data = this.menuService.getApps()
var self = this;
var rec_ids = []
menu_data.map(app => rec_ids.push(app.id))
this.rpc('/get/menu_data',{'menu_ids':rec_ids,
}).then(function(rec) {
console.log(rec);
$.each(menu_data, function( key, menu ) {
var target_elem = '.primary-nav a.main_link[data-menu='+ menu.id+']'
var elem = $(self.root.el).find(target_elem)
elem.find('.app_icon').empty()
var pr_record = rec[menu.id][0]
menu.id = pr_record.id
menu.use_icon = pr_record.use_icon
menu.icon_class_name = pr_record.icon_class_name
menu.icon_img = pr_record.icon_img
if (pr_record.use_icon) {
if (pr_record.icon_class_name) {
var icon_image = "<span class='ri "+pr_record.icon_class_name+"'/>"
} else if (pr_record.icon_img) {
var icon_image = "<img class='img img-fluid' src='/web/image/ir.ui.menu/"+pr_record.id+"/icon_img' />"
} else if (pr_record.web_icon != false) {
var icon_data = pr_record.web_icon.split('/icon.')
if (icon_data[1] == 'svg'){
var web_svg_icon = pr_record.web_icon.replace(',', '/')
var icon_image = "<img class='img img-fluid' src='"+web_svg_icon+"' />"
} else {
var icon_image = "<img class='img img-fluid' src='data:image/"+icon_data[1]+";base64,"+pr_record.web_icon_data+"' />"
}
} else{
var icon_image = "<img class='img img-fluid' src='/clarity_backend_theme_bits/static/img/logo.png' />"
}
elem.find('.app_icon').append($(icon_image))
} else {
if (pr_record.icon_img) {
var icon_image = "<img class='img img-fluid' src='/web/image/ir.ui.menu/"+pr_record.id+"/icon_img' />"
} else if (pr_record.web_icon != false){
var icon_data = pr_record.web_icon.split('/icon.')
if (icon_data[1] == 'svg'){
var web_svg_icon = pr_record.web_icon.replace(',', '/')
var icon_image = "<img class='img img-fluid' src='"+web_svg_icon+"' />"
} else {
var icon_image = "<img class='img img-fluid' src='data:image/"+icon_data[1]+";base64,"+pr_record.web_icon_data+"' />"
}
} else{
var icon_image = "<img class='img img-fluid' src='/clarity_backend_theme_bits/static/img/logo.png' />"
}
elem.find('.app_icon').append($(icon_image))
}
});
})
},
BackMenuToggle(ev){
$(ev.currentTarget).parent().removeClass('show');
},
get currentMenuId() {
var actionParams = window.location.hash;
var menu_id = new URLSearchParams(actionParams.substring(1)).get('menu_id');
return menu_id;
}
});
patch(WebClient, {
components: { ...WebClient.components, SidebarBottom },
});
@@ -0,0 +1,21 @@
/** @odoo-module **/
import { NavBar } from '@web/webclient/navbar/navbar';
import { useService, useBus } from '@web/core/utils/hooks';
import { patch } from "@web/core/utils/patch";
import { useEnvDebugContext } from "@web/core/debug/debug_context";
patch(NavBar.prototype, {
setup() {
super.setup();
this.debugContext = useEnvDebugContext();
this.rpc = useService('rpc');
this.companyService = useService("company");
this.currentCompany = this.companyService.currentCompany;
this.menuService = useService("menu");
},
toggleSidebar(ev){
$(ev.currentTarget).toggleClass('visible');
$('.nav-wrapper-bits').toggleClass('toggle-show');
},
});
@@ -0,0 +1,664 @@
body.o_web_client{
flex-flow: row !important;
.wrapper-container-bits{
display: flex;
width: 100%;
.content-wrapper-bits{
width: 100%;
overflow-x: clip;
@media (max-width: 1540px) {
height: 100%;
// overflow: auto;
}
.btn-link{
color: #282828 !important;
}
.btn.btn-primary{
background-color: #282828 !important;
color: #fff !important;
border-color: #fff;
border: 1px solid #282828;
&:focus,&:active,&:hover{
background-color: #fff !important;
color: #282828 !important;
border-color: #282828 !important;
}
}
.btn.btn-secondary{
background-color: #fff !important;
color: #282828 !important;
border-color: #282828;
border: 1px solid #282828;
&:focus,&:active,&:hover{
background-color: #282828 !important;
color: #fff !important;
border-color: #282828 !important;
}
}
.o_main_navbar{
padding: 0 10px;
.o_menu_systray{
align-items: center;
.o_user_menu{
display: none !important;
}
button.dropdown-toggle{
background-color: #282828;
margin: 0px 4px;
width: 35px;
height: 35px;
text-align: center;
justify-content: center;
border-radius: 6px;
i{
color: #fff;
font-size: 16px !important;
}
.badge.rounded-pill{
position: absolute;
right: -10px;
top: 2px;
background-color: #ffffff;
border-color: #282828;
border: 1px solid #282828;
color: #282828;
}
&.o_mobile_menu_toggle{
padding: 15px !important;
}
}
.o_mobile_preview{
a.o_nav_entry{
}
}
.o_website_switcher_container,.o_edit_website_container,.o_new_content_container,.o_mobile_preview{
button.dropdown-toggle,a.o_nav_entry,.o_nav_entry,a.btn{
width: auto !important;
background-color: #282828 !important;
margin: 0px 4px;
height: 35px !important;
text-align: center;
justify-content: center;
border-radius: 6px !important;
color: #fff !important;
}
}
.o_menu_systray_item{
a{
.d-none.d-md-block.ms-1{
color: #282828 !important;
}
}
}
// header button popup
.o-mail-DiscussSystray{
box-shadow: 0px 1px 5px #abababed;
border-radius: 16px;
.o-mail-MessagingMenu-header{
button.fw-bold{
border-bottom: 1px solid #282828;
}
}
}
.o_mobile_menu_toggle{
display: none !important;
}
}
.sidebar-toggler{
cursor: pointer;
.sidebar-toggle-bits{
font-size: 12px;
color: #282828;
i.back-arrow{
width: 0px !important;
visibility: hidden;
opacity: 0;
}
}
&:hover{
.sidebar-toggle-bits{
i.toggle{
width: 0px !important;
display: none !important;
}
i.back-arrow{
visibility: visible;
opacity: 1;
transition: all 0.2s;
width: 100% !important;
font-size: 18px;
font-weight: 600;
margin-top: 4px;
}
}
}
}
}
.o_action_manager{
height: 100%;
width: 100%;
.o_control_panel{
padding: 10px 14px !important;
.o_control_panel_main{
// create button
.o_control_panel_breadcrumbs{
.o_control_panel_main_buttons{
.btn-outline-primary{
color: #282828 !important;
border-color: #282828 !important;
&:hover,&:focus,&:active{
color: #fff !important;
background-color: #282828 !important;
}
}
}
.breadcrumb{
.breadcrumb-item{
a{
color: #282828 !important;
}
}
}
}
// action button
.o_control_panel_actions{
.btn-outline-secondary{
border-color: #282828 !important;
i{
color: #282828 !important;
}
span{
color: #282828 !important;
}
}
.o_cp_searchview .o_searchview{
border-radius: 8px 1px 1px 8px;
border-color: #282828;
}
.o-dropdown{
button.o_searchview_dropdown_toggler{
border-radius: 0px 8px 8px 0px;
}
}
.o_search_bar_menu{
i{
color: #282828 !important;
}
}
}
// navigation
.o_control_panel_navigation{
.o_pager_counter{
span{
font-size: 18px;
}
}
button{
font-size: 0.875rem;
border-radius: 6px !important;
border-color: #282828;
background-color: #fff !important;
color: #282828 !important;
height: 35px;
margin: 0px 3px;
&.active{
background-color: #2828282e !important;
}
// width: 35px;
@media (max-width: 768px) {
width:auto !important;
}
}
}
}
}
// Discuss module in community
.o-mail-Discuss{
width: 100%;
}
.o_content{
overflow: auto !important;
height: 100%;
margin-bottom: 60px;
max-height: calc(100vh - 100px);
}
// config setting view
.o-settings-form-view{
.o_setting_container{
.settings_tab{
.app_name{
font-size: 15px !important;
}
}
}
}
// form view
.o_form_view_container{
.o_form_sheet_bg{
.o_form_statusbar{
overflow: hidden;
.o_statusbar_buttons{
.btn-primary{
background-color: #71639e !important;
border-color: #71639e !important;
&:hover{
background-color: #fff !important;
}
}
.btn-secondary{
background-color: #fff !important;
border-color: #71639e !important;
&:hover{
background-color: #71639e !important;
}
}
}
.o_arrow_button{
border-color: #71639e !important;
background-color: #fff;
&:after{
border-color: #fff;
}
}
.o_statusbar_status{
.o_arrow_button{
border: none !important;
}
}
////////////////////////////////////////////////////////////////
.o_statusbar_status {
.o_arrow_button {
font-size: 14px;
text-align: center;
cursor: default;
margin: 0 3px;
padding: 5px 25px;
float: left;
position: relative;
background-color: #d9e3f7 !important;
user-select: none;
transition: background-color 0.2s ease;
&:after,&:before{
content: " ";
position: absolute;
top: 0;
right: -17px;
width: 0;
height: 0;
border-top: 15px solid transparent;
border-bottom: 15px solid transparent;
border-left: 17px solid #d9e3f7;
z-index: 2;
transition: border-color 0.2s ease;
}
&:hover{
color: #282828 !important;
}
&:before{
right: auto;
left: 0;
border-left: 17px solid #f8f9fa;
z-index: 0;
}
&:first-child{
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
&:before {
border: none;
}
}
&.o_arrow_button_current{
color: #fff !important;
span{
color: #fff !important;
}
background-color: #71639e !important;
&:after{
border-left: 17px solid #71639e;
}
}
}
}
}
////////////////////////////////////////////////////////////////
.o_form_sheet{
border-radius: 8px;
box-shadow: 0px 0px 3px #919191;
border: none;
.o_cell{
label,span,a{
font-size: 15px !important;
}
}
.o_form_uri{
span:first-child{
color: #282828 !important;
}
}
.o_notebook{
.o_notebook_headers{
.nav.nav-tabs{
border-top: 1px solid #dee2e6;
padding: 0px !important;
.nav-item .nav-link{
color: #484848;
display: block;
border-right: 1px solid #2828286b !important;
padding: 10px;
font-weight: 500;
&:after{
height: 5px;
background-color: #282828;
}
&:before{
height: 5px;
background-color: #282828;
}
&.active{
border-bottom: 2px solid #31485e;
background: #f9f9f9 !important;
font-weight: 600;
}
}
}
}
}
}
.o_list_renderer{
table{
a{
color: #000730 !important;
}
}
}
}
}
// kanban view
.o_kanban_view{
.o_kanban_record{
margin: 14px 5px 0px !important;
border-radius: 15px;
.oe_kanban_card,.oe_kanban_global_click{
border-radius: 8px;
border-color: #2828286e;
border: 1px solid #28282812;
box-shadow: 0px 3px 4px 0px rgba(0, 0, 0, 0.03);
padding: 14px;
}
}
}
// list view
.o_list_view.o_action{
height: 100%;
.o_content{
padding: 10px 14px;
}
.o_list_renderer{
border: 0px !important;
border-radius: 8px;
box-shadow: 0px 0px 3px #919191;
.o_list_table{
table-layout: auto !important;
thead{
th{
padding: 10px 12px;
background-color: #282828;
color: #fff !important;
button{
color: #fff !important;
}
.form-check-input{
background-color: #fff !important;
}
}
}
tbody{
tr{
border-color: #28282899;
border: none ;
td{
border: none;
padding: 14px 12px;
color: #282828 !important;
font-size: 15px !important;
font-weight: 500;
}
&.o_data_row{
border-bottom-width: 1px !important;
border-bottom-style: dashed !important;
}
}
box-shadow: 0px 1px 2px #e2e2e2;
border-radius: 12px;
}
tfoot{
tr{
td{
border: none;
padding: 10px 12px;
color: #282828 !important;
}
}
}
}
.form-check{
.form-check-input{
&:checked{
background-color: #282828 !important;
border-color: #282828 !important;
}
}
}
}
}
// graph view
.o_graph_view {
.o_content {
height: calc(100vh - 100px);
}
}
// discuss view
.o-mail-Discuss{
background: #fff !important;
.o-mail-DiscussSidebar{
margin: 7px;
border: none !important;
box-shadow: 0px 1px 4px #9191912e;
border-radius: 14px;
.o-mail-DiscussSidebar-item{
background: #e3e3e39e;
color: #282828 !important;
border-radius: 7px !important;
margin: 5px 10px;
padding: 10px 0 !important;
font-weight: 600 !important;
}
}
.o-mail-Discuss-content{
overflow: scroll !important;
.o-mail-Discuss-header{
border-bottom: none !important;
}
.o-mail-Thread{
overflow: scroll;
margin: 7px;
box-shadow: 0px 0px 6px #413d3d3b !important;
border: 1px solid #28282800;
border-radius: 14px;
//msg section
.o-mail-Message{
margin-top: 16px !important;
.o-mail-Message-core{
//right content / msg content
.o-min-width-0{
.o-mail-Message-header{
.o-mail-Message-author{
font-size: 16px;
margin: 8px 0px;
}
}
.o-mail-Message-content{
.o-mail-Message-bubble{
border-radius: 0px 10px 6px 10px !important;
.o-mail-Message-body{
padding: 15px 25px !important;
}
}
}
}
}
}
}
.o-mail-Composer{
.o-mail-Composer-coreMain{
.btn{
color: #282828 !important;
}
.o-mail-Composer-send{
background: #282828 !important;
margin: 0 !important;
opacity: 1;
color: #fff !important;
}
}
}
}
}
}
#terabits-link{
h2{
padding: 12px 28px;
background: #eee;
font-size: 15px !important;
}
}
}
}
&.editor_has_snippets_hide_backend_navbar{
.nav-wrapper-bits{
display: none;
}
}
}
.menu {
display: block;
width: 250px;
height: 100%;
transition: all 0.45s cubic-bezier(0.77, 0, 0.175, 1);
z-index: 999;
.icon {
position: absolute;
top: 12px;
right: 10px;
pointer-events: none;
width: 24px;
height: 24px;
color: #fff;
}
a {
display: block;
white-space: nowrap;
}
}
.menu,
.menu a,
.menu a:visited {
color: #aaa;
text-decoration: none!important;
position: relative;
}
.new-wrapper {
position: absolute;
left: 50px;
width: calc(100% - 50px);
transition: transform .45s cubic-bezier(0.77, 0, 0.175, 1);
}
#menu:checked + ul.menu-dropdown {
left: 0;
-webkit-animation: all .45s cubic-bezier(0.77, 0, 0.175, 1);
animation: all .45s cubic-bezier(0.77, 0, 0.175, 1);
}
.sub-menu-checkbox:checked + ul.sub-menu-dropdown {
display: block!important;
-webkit-animation: grow .45s cubic-bezier(0.77, 0, 0.175, 1);
animation: grow .45s cubic-bezier(0.77, 0, 0.175, 1);
}
.openNav .new-wrapper {
position: absolute;
transform: translate3d(200px, 0, 0);
width: calc(100% - 250px);
transition: transform .45s cubic-bezier(0.77, 0, 0.175, 1);
}
.downarrow {
background: transparent;
position: absolute;
right: 50px;
top: 12px;
color: #777;
width: 24px;
height: 24px;
text-align: center;
display: block;
}
.downarrow:hover {
color: #fff;
}
.menu-dropdown {
top: 0;
overflow-y: auto;
}
.overflow-container {
position: relative;
height: 100% !important;
overflow-y: auto;
z-index: -1;
display:block;
}
.sub-menu-dropdown {
background-color: #333;
}
.openNav .menu {
top: 73px;
transform: translate3d(200px, 0, 0);
transition: transform .45s cubic-bezier(0.77, 0, 0.175, 1);
}
/* look and feel only, not needed for core menu*/
@-webkit-keyframes grow {
0% {
display: none;
opacity: 0;
}
50% {
display: block;
opacity: 0.5;
}
100% {
opacity: 1;
}
}
@keyframes grow {
0% {
display: none;
opacity: 0;
}
50% {
display: block;
opacity: 0.5;
}
100% {
opacity: 1
}
}
@@ -0,0 +1,69 @@
#wrapwrap{
.login-view-bits{
.oe_login_form,.oe_signup_form,.oe_reset_password_form{
.input-group{
a.btn{
background-color: #282828;
color: #fff !important;
border-radius: 0px 8px 8px 0px !important;
display: flex !important;
align-items: center;
i{
color: #fff !important;
padding-left: 5px;
margin-top: -4px;
}
}
}
input,.form-control{
display: block;
width: 100%;
padding: 0.775rem 1rem;
font-size: 1.1rem;
font-weight: 500;
line-height: 1.5;
color: #4B5675;
appearance: none;
background-clip: padding-box;
border: 1px solid #DBDFE9;
border-radius: 0.475rem;
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
&#db{
border-radius: 8px 0px 0px 8px !important;
}
}
.col-form-label,.form-label{
font-size: 14px !important;
font-weight: bold !important;
}
}
.card-body{
box-shadow: 0px 0px 10px #d2d1d1;
border-radius: 30px;
}
.oe_login_buttons{
.btn-primary[type=submit]{
padding: 14px;
border-radius: 8px;
background: #282828;
color: #fff;
font-size: 14px;
&:hover,&:active,&:focus{
color: #282828;
background: #fff;
border: 1px solid #282828;
}
}
a,button.btn{
font-size: 12px;
font-weight: 600;
}
}
div.small{
a,button.btn{
font-size: 12px;
font-weight: 600;
}
}
}
}
@@ -0,0 +1,211 @@
body.o_web_client{
.nav-wrapper-bits{
display: none ;
&.toggle-show{
display: flex;
flex-direction: column;
justify-content: space-between;
background-color: #282828;
height: 100%;
z-index: 999;
header{
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.sytray-container-bits{
margin: 5px 5px;
background-color: none !important;
button{
width: 100%;
border: none !important;
box-shadow: none !important;
background: #343434;
border-radius: 10px;
img{
width: 35px;
border-radius: 30px !important;
}
}
mark{
font-size: 14px;
margin-top: 8px;
background: #fff !important;
padding: 7px;
border-radius: 8px;
}
.o_user_menu{
.o-dropdown--menu{
min-width: 15rem !important;
.dropdown-item{
padding: 5px 20px !important;
}
}
}
.powered-by{
display: none;
}
&:hover{
.powered-by{
display: block !important;
color: #fff;
a{
color: #aab6ff !important;
}
}
}
}
}
.btm-user-menu{
z-index: 999;
width: 250px;
}
@media (max-width: 768px) {
position: absolute;
top: 0;
bottom: 0;
height: 100%;
z-index: 11;
}
}
header.o_navbar{
nav{
background-color: transparent !important;
border-bottom: none !important;
}
.o_company_logo{
padding: 8px 20px !important;
display: flex;
align-items: center;
justify-content: space-between;
background: #343434;
border-radius: 10px;
margin: 5px 5px;
i{
color: #fff !important;
font-size: 20px;
display: none;
@media (max-width: 768px) {
display: block;
}
}
img{
width: 150px;
height: 70px;
object-fit: contain;
}
}
}
.primary-nav{
flex: 1 1 0 !important;
overflow-y: auto;
.overflow-container{
.main_link{
.app_icon{
height: 25px !important;
width: 25px !important;
display: inline-flex;
img{
object-fit: contain;
}
}
}
}
ul#menu-dropdown{
list-style-type: none !important;
padding-left: 5px !important;
li a.main_link{
display: flex;
align-items: center !important;
padding: 1em;
font-size: 14px;
}
ul.header-sub-menus.main{
list-style-type: none !important;
z-index: 3;
position: absolute;
left: 0;
background-color: #282828 !important;
height: 100%;
top: 0;
width: 100%;
padding: 0px 12px;
// &:not(.show){
// left: 100% !important;
// }
&:not(.show){
display: none;
width: 0% ;
}
.back_main_menu{
position: relative;
margin-left: -18px;
h3{
color: #ffff !important;
cursor: pointer;
}
}
li{
margin-left: 10px ;
background: #282828;
.header-sub-menus{
list-style-type: none !important;
border-left: 1px solid #717171;
padding: 0;
}
.sub-main-menu{
cursor: pointer !important;
font-size: 14px;
color: #fff;
font-weight: 600;
background: #282828;
}
}
@media (max-width: 768px) {
position: relative !important;
.back_main_menu{
display: none !important;
}
}
// &.show{
// li{
// .collapse{
// display: block;
// }
// }
// }
a{
padding: 0.5rem !important;
font-size: 12px !important;
}
&.show{
li{
.sub-main-menu{
background: #eeeeee14;
padding: 5px 10px !important;
border-radius: 8px;
margin: 8px 0px;
}
}
}
}
}
::-webkit-scrollbar-track
{
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
background-color: #F5F5F5;
}
::-webkit-scrollbar
{
width: 6px;
background-color: #F5F5F5;
}
::-webkit-scrollbar-thumb
{
background-color: #575757;
}
}
}
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-inherit="web.WebClient" t-inherit-mode="extension" owl="1">
<xpath expr="//ActionContainer" position="replace"/>
<xpath expr="//MainComponentsContainer" position="replace"/>
<xpath expr="//t" position="replace">
<div class="wrapper-container-bits">
<div class="nav-wrapper-bits toggle-show">
<header class="o_navbar" t-ref="root">
<div class="o_company_logo p-3">
<div class="d-flex justify-content-between w-100 align-items-center">
<t t-if="currentCompany">
<img class="img img-fluid company_logo" t-attf-src="/web/image?model=res.company&amp;field=logo&amp;id={{currentCompany.id}}"/>
<img class="img img-fluid company_logo_icon d-none" t-attf-src="/web/image?model=res.company&amp;field=logo_icon&amp;id={{currentCompany.id}}"/>
</t>
<i class="fa fa-bars fa-2x" t-on-click="toggleSidebar"/>
</div>
</div>
<!-- Apps Menu -->
<t t-call="web.NavBar.AppsMenu">
<!-- <t t-set="apps" t-value="menuService.getApps()" /> -->
</t>
<div class="btm-user-menu d-block">
<SidebarBottom/>
</div>
</header>
</div>
<div class="content-wrapper-bits">
<t t-if="!state.fullscreen">
<NavBar/>
</t>
<ActionContainer/>
<MainComponentsContainer/>
</div>
</div>
</xpath>
</t>
</templates>
@@ -0,0 +1,132 @@
<templates id="template" xml:space="preserve">
<t t-inherit="web.NavBar.AppsMenu" t-inherit-mode="extension" owl="1">
<xpath expr="//Dropdown" position="replace">
<nav role="navigation" class="primary-nav menu o_main_navbar" data-command-category="disabled">
<div class="overflow-container">
<t t-set="curr_app" t-value="currentMenuId? menuService.getMenuAsTree(currentMenuId): null"/>
<ul id="menu-dropdown">
<t t-foreach="menuService.getApps()" t-as="main_menu" t-key="main_menu.name">
<t t-if="!main_menu.children.length">
<li>
<a t-attf-href="#menu_id={{main_menu.id}}&amp;action={{main_menu.actionID ? main_menu.actionID : ''}}"
t-att-data-menu="main_menu.id"
t-attf-data-action-model="{{main_menu.actionModel ? main_menu.actionModel : ''}}"
t-attf-data-action-id="{{main_menu.actionID ? main_menu.actionID : ''}}"
t-att-data-menu-xmlid="main_menu.xmlid" t-attf-class="main_link">
<span class="app_icon me-2"></span>
<span>
<t t-esc="main_menu.name" />
</span>
</a>
</li>
</t>
<t t-else="">
<li class="menu-hasdropdown">
<a t-attf-href="#menu_id={{main_menu.id}}&amp;action={{main_menu.actionID ? main_menu.actionID : ''}}" t-att-data-menu="main_menu.id"
t-attf-data-action-model="{{main_menu.actionModel ? main_menu.actionModel : ''}}"
t-attf-data-action-id="{{main_menu.actionID ? main_menu.actionID : ''}}"
t-att-data-menu-xmlid="main_menu.xmlid" t-attf-class="main_link dropdown-btn"
t-attf-data-bs-target="#child_menu_{{main_menu.id}}"
data-bs-toggle="collapse">
<span class="app_icon me-2"></span>
<span>
<t t-esc="main_menu.name" />
</span>
<span class="oi oi-chevron-right ms-auto p-2" />
</a>
<ul t-attf-class="main header-sub-menus sub-menu-dropdown collapse #{curr_app &amp;&amp; curr_app.appID == main_menu.appID ?'show':''}" t-attf-id="child_menu_{{main_menu.id}}">
<a class="back_main_menu collapse_back d-flex align-items-center" t-on-click="BackMenuToggle">
<span class="oi oi-chevron-left p-2" />
<h3 class="m-0 p-o">
<b>
<t t-esc="main_menu.name" />
</b>
</h3>
</a>
<t t-set="parent_menu_id" t-value="main_menu.id" />
<t t-foreach="main_menu.children" t-as="menuid" t-key="menuid">
<t t-set="menu" t-value="menuService.getMenuAsTree(menuid)"/>
<t t-call="AllmenuRecursive">
</t>
</t>
<t t-if="main_menu.xmlid == 'base.menu_administration'">
<li>
<a class="d-flex align-items-center w-100 sub-main-menu" data-bs-toggle="collapse" t-attf-data-bs-target="#child_menu_theme">
<span>Backend Theme</span>
<span class="oi oi-chevron-right ms-auto p-2" />
</a>
<div t-attf-id="child_menu_theme" class="collapse">
<ul class="header-sub-menus">
<li class="nav-item">
<a class="child_menus" href="https://www.terabits.xyz/survey/start/0261438c-36bd-4f73-a63d-9120a4d4764d" target="_blank">
<span>Leave a review</span>
</a>
</li>
<li class="nav-item">
<a class="child_menus" href="https://www.terabits.xyz/survey/start/9e8fe56d-b8b4-4c34-b3b6-513b08ab513e">
<span>Get regular updates</span>
</a>
</li>
<li class="nav-item">
<a class="child_menus" href="https://www.terabits.xyz/services/debranding">
<span>Debrand your ERP</span>
</a>
</li>
</ul>
</div>
</li>
</t>
</ul>
</li>
</t>
</t>
</ul>
</div>
</nav>
</xpath>
</t>
<t t-inherit="web.NavBar" t-inherit-mode="extension" owl="1">
<xpath expr="//t[@t-call='web.NavBar.AppsMenu']" position="replace">
</xpath>
<xpath expr="//t[@t-call='web.NavBar.SectionsMenu']" position="replace"></xpath>
<xpath expr="//DropdownItem" position="after">
<div class="sidebar-toggler d-flex align-items-center">
<a href="javascript:;" class="sidebar-toggle-bits ms-1" t-on-click="toggleSidebar">
<i class="toggle fa fa-bars fa-2x"/>
<i class="back-arrow oi oi-chevron-left fa-2x"/>
</a>
<t t-if="currentApp">
<h4 class="ms-2 mb-0"><t t-esc="currentApp.name"/></h4>
</t>
</div>
</xpath>
<xpath expr="//DropdownItem" position="replace"/>
</t>
<t t-name="AllmenuRecursive" owl="1">
<li class="nav-item">
<t t-if="menu.childrenTree.length">
<a class="d-flex align-items-center w-100 sub-main-menu" data-bs-toggle="collapse" t-attf-data-bs-target="#child_menu_{{menu.id}}" t-att-data-menu-xmlid="menu.xmlid">
<span><t t-esc="menu.name"/></span>
<span class="oi oi-chevron-right ms-auto p-2" />
</a>
<div t-attf-id="child_menu_{{menu.id}}" class="collapse">
<ul class="header-sub-menus">
<t t-foreach="menu.children" t-as="menuid" t-key="menuid">
<t t-set="menu" t-value="menuService.getMenuAsTree(menuid)"/>
<t t-call="AllmenuRecursive" />
</t>
</ul>
</div>
</t>
<t t-else="">
<a t-att-data-menu="menu.id" t-attf-class="child_menus" t-attf-href="#menu_id={{menu.id}}&amp;action={{menu.actionID ? menu.actionID : ''}}" t-att-data-menu-xmlid="menu.xmlid" t-attf-data-action-id="{{menu.actionID ? menu.actionID : ''}}">
<span class="app_name">
<t t-esc="menu.name" />
</span>
</a>
</t>
</li>
</t>
</templates>
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<templates>
<t t-inherit="web.UserMenu" t-inherit-mode="extension" owl="1">
<xpath expr="//t[@t-set-slot='toggler']" position="replace">
<t t-set-slot="toggler">
<img class="o_avatar o_user_avatar rounded" t-att-src="source" alt="User"/>
</t>
</xpath>
</t>
<t t-name="SidebarBottom" >
<div class='sytray-container-bits'>
<Dropdown class="'o_user_menu pe-0'" togglerClass="'py-1 py-lg-0'">
<t t-set-slot="toggler">
<div class="user-avtar-bits d-block py-3">
<div class="d-flex align-items-center">
<div>
<img class="o_avatar o_user_avatar rounded" t-att-src="source" t-att-alt="user.name"/>
</div>
<span class="oe_topbar_name ms-2 lh-1 text-truncate mb-0 py-2 text-white d-block" >
<t t-esc="user.name"/>
</span>
</div>
<div class="oe_topbar_name text-start smaller lh-1 text-truncate w-100" t-att-class="{'d-lg-inline-block' : env.debug}" >
<mark class="d-block font-monospace text-truncate">
<i class="fa fa-database oi-small me-1"/><t t-esc="user.db.name"/>
</mark>
</div>
<div class="powered-by">
Powered By<a href="https://www.terabits.xyz/contact-us" class="btn btn-link btn-sm">Terabits Technolab</a>
</div>
</div>
</t>
<t t-foreach="getElements()" t-as="element" t-key="element_index">
<t t-if="!element.hide">
<DropdownItem
t-if="element.type == 'item' || element.type == 'switch'"
href="element.href"
dataset="{ menu: element.id }"
onSelected="element.callback"
>
<CheckBox
t-if="element.type == 'switch'"
value="element.isChecked"
className="'form-switch d-flex flex-row-reverse justify-content-between p-0 w-100'"
onChange="element.callback"
>
<t t-out="element.description"/>
</CheckBox>
<t t-else="" t-out="element.description"/>
</DropdownItem>
<div t-if="element.type == 'separator'" role="separator" class="dropdown-divider"/>
</t>
</t>
</Dropdown>
</div>
</t>
<t t-inherit="web.SwitchCompanyMenu" t-inherit-mode="extension">
<xpath expr="//t[@t-set-slot='toggler']" position="replace">
<t t-set-slot="toggler">
<i class="fa fa-building" title="Switch Company"/>
</t>
</xpath>
</t>
</templates>
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.base</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="1000"></field>
<field name="inherit_id" ref="base.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//form" position="inside">
<div id="terabits-link">
<block title="Clarity backend theme" name="links_container">
<div class="d-block">
<div>
<h6 class="mb-3">
Clarity Backend Theme - Powered by <a href="https://terabits.xyz?ref=clarity_backend_theme" target="_blank">Terabits Technolab</a>
</h6>
</div>
</div>
<div>
<h6>
Easily set correct access rights with <a href="https://apps.odoo.com/apps/modules/17.0/simplify_access_management/" target="_blank" title="Terabits Technolab">Simplify Access Management</a> app.
</h6>
</div>
</block>
</div>
</xpath>
</field>
</record>
</odoo>
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_users_form" model="ir.ui.view">
<field name="name">res.users.form</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form" />
<field name="arch" type="xml">
<xpath expr="//page[@name='access_rights']" position="inside">
<!-- <separator string="Don't know how to set correct access rights for multiple users?" class=""/> -->
<div class="o_horizontal_separator mt-4 mb-3 text-uppercase fw-bolder bg-300 py-4 rounded px-2">Don't know how to set correct access rights for multiple users?</div>
<div>
<div class="d-block">
<h5 class="mt-2">Easily set with <a href="https://apps.odoo.com/apps/modules/17.0/simplify_access_management/" title="terabits">Simplify Access Management</a> app.</h5>
<h5 class="mt-2">
Live demo available
<a href="https://www.terabits.xyz/request_demo?source=clarity_backend_theme&amp;version=17&amp;app=simplify_access_management" title="terabits">Access Here.</a>
</h5>
</div>
</div>
</xpath>
</field>
</record>
</odoo>
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="login_layout_bits" inherit_id="web.login_layout" name="login layout">
<!-- <xpath expr="//div[@class='container py-5']" position="attributes">
<attribute name="class">container py-5 login-view-bits</attribute>
</xpath> -->
<xpath expr="//div[@class='container py-5']" position="replace">
<div class="container py-5 login-view-bits">
<div class="row justify-content-center">
<div class="col-12 col-md-4 col-lg-4">
<div t-attf-class="card border-0 mx-auto bg-100 {{login_card_classes}} o_database_list">
<div class="card-body">
<div t-attf-class="text-center pb-3 border-bottom {{'mb-3' if form_small else 'mb-4'}}">
<img t-attf-src="/web/binary/company_logo{{ '?dbname='+db if db else '' }}" alt="Logo" style="max-height:120px; max-width: 100%; width:auto"/>
</div>
<t t-out="0"/>
<div class="text-center small mt-4 pt-3 border-top" t-if="not disable_footer">
<t t-if="not disable_database_manager">
<a class="border-end pe-2 me-1" href="/web/database/manager">Manage Databases</a>
</t>
<a href="https://www.odoo.com?utm_source=db&amp;utm_medium=auth" target="_blank">Powered by <span>Odoo</span></a>
</div>
</div>
</div>
</div>
</div>
</div>
</xpath>
</template>
</odoo>
+5
View File
@@ -0,0 +1,5 @@
允许通过激活码延长数据库过期时间
增加database.partner,数据库合作伙伴系统参数以区分客户
此模块为客户使用模块,还有一个激活码签发模块。
+3
View File
@@ -0,0 +1,3 @@
# Copyright 2014-2016 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models
+23
View File
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
{
"name": "数据库过期时间激活码",
"description": """
允许通过激活码延长数据库过期时间
""",
"author": "songbo",
"website": "https://www.pengyuthon.com/",
"category": "Customizations/Studio",
"version": "17.0.0.1",
"depends": ["web_enterprise", "mail"],
"external_dependencies": {
"python": ["rsa"],
},
"data": ["data/account_report_actions.xml"],
"assets": {
"web.assets_backend": [
"database_activation_code/static/src/webclient/**/*.xml",
],
},
"installable": True,
"auto_install": False,
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.config_parameter" id="database_activation_code_partner" forcecreate="False">
<field name="key">database.partner</field>
<field name="value">base</field>
</record>
</odoo>
@@ -0,0 +1,2 @@
from . import update
from . import ir_http
@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
from odoo import models
from odoo.http import request
class Http(models.AbstractModel):
_inherit = "ir.http"
def session_info(self):
ICP = self.env["ir.config_parameter"].sudo()
User = self.env["res.users"]
if User.has_group("base.group_system"):
warn_enterprise = "admin"
elif User.has_group("base.group_user"):
warn_enterprise = "user"
else:
warn_enterprise = False
result = super(Http, self).session_info()
result["support_url"] = "https://www.pengyuthon.com//help"
if warn_enterprise:
result["warning"] = warn_enterprise
result["expiration_date"] = ICP.get_param("database.expiration_date")
result["expiration_reason"] = ICP.get_param("database.expiration_reason")
return result
+74
View File
@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import datetime
import logging
import rsa
import base64
from os.path import join as opj
from odoo.modules import get_module_path
from odoo import api, release, SUPERUSER_ID
from odoo.exceptions import UserError
from odoo.models import AbstractModel
_logger = logging.getLogger(__name__)
class PublisherWarrantyContract(AbstractModel):
_inherit = "publisher_warranty.contract"
# rsa解密
def rsaDecrypt(self, str1):
modpath = get_module_path("database_activation_code")
file_path = opj(modpath, "static", "privkey.pem")
with open(file_path) as privatefile:
p = privatefile.read()
# 验证密钥
try:
privkey = rsa.PrivateKey.load_pkcs1(p)
except:
raise UserError("请联系管理员!")
try:
str1 = base64.b16decode(str1)
# 私钥解密
content = rsa.decrypt(str1, privkey)
con = content.decode("utf-8").split("#")
if len(con) != 2:
raise
database_partner = con[0]
old_database_partner = (
self.sudo().env["ir.config_parameter"].get_param("database.partner")
)
if database_partner != old_database_partner:
raise
expiration_date = con[1]
old_enterprise_code = (
self.sudo()
.env["ir.config_parameter"]
.get_param("database.expiration_date")
)
except:
raise UserError("激活码错误")
if expiration_date <= old_enterprise_code:
raise UserError("激活码已过期")
# 设置过期时间
set_param = self.env["ir.config_parameter"].sudo().set_param
set_param("database.expiration_date", expiration_date)
def update_notification(self, cron_mode=True):
# 获取激活码
enterprise_code = (
self.sudo().env["ir.config_parameter"].get_param("database.enterprise_code")
)
if enterprise_code:
try:
enterprise_code = str.encode(enterprise_code)
except:
raise UserError("激活码错误")
# 验证激活码
self.rsaDecrypt(enterprise_code)
return True
@@ -0,0 +1,9 @@
-----BEGIN RSA PRIVATE KEY-----
MIIBPAIBAAJBAIfrf/oF/janGFgNeu0Y3YWoVg9SB3msMhfKq6q4G1t9gqdodLYs
oc2vNgUd7689231R+vvLGdKzBizDJZVh3tMCAwEAAQJAZTKvX1108AYrNuwaeUuJ
K8mxAckmba4KwfIRLJPUxvUvrKDkRwmQCNQ6/FF8UFiYexwu19wOPSYsdiq4b6eT
qQIjAJCfBBtskYgfT0qdcPu9NlE++vyTG/QZVlXOCEIr4WcB7BUCHwDwmPrY/nOU
nek6/QawqfkUZh7SO7rc/5KMp6V8EUcCImWpMmTow8CxabakyAheMLGaGSq1aqAD
s5nrlAiX+gHD6yUCHwDPZjAmygF8RTt9/Au+UmdCbF15QL/uLel4kjOW5ZUCImOr
yrfsjcjVr3+nXOqYdR+/Q+6q6sMBRC1Nn2+pbgI5dRY=
-----END RSA PRIVATE KEY-----
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="database_activation_code.DatabaseExpirationPanel" t-inherit="web_enterprise.DatabaseExpirationPanel" t-inherit-mode="extension">
<xpath expr="//a[hasclass('oe_instance_buy')]" position="replace">
<a class="oe_instance_buy alert-link text-decoration-underline" href="https://www.pengyuthon.com/">联系我们</a>.
</xpath>
</t>
</templates>