From 90bc0679b46e7ef6e30e9eb3ff8b84acd4bf5d1f Mon Sep 17 00:00:00 2001 From: Altahir Hassan Date: Tue, 20 Jan 2026 17:07:38 +0400 Subject: [PATCH] feat: Enhance sidebar settings with color schema and background options --- .../models/res_config_settings.py | 194 +++- .../static/src/scss/sidebar_menu.scss | 865 +++++++++--------- .../views/res_config_settings.xml | 22 +- 3 files changed, 633 insertions(+), 448 deletions(-) diff --git a/odex30_base/odex_sidebar_backend_theme2/models/res_config_settings.py b/odex30_base/odex_sidebar_backend_theme2/models/res_config_settings.py index e4a2fda..f88a6d9 100644 --- a/odex30_base/odex_sidebar_backend_theme2/models/res_config_settings.py +++ b/odex30_base/odex_sidebar_backend_theme2/models/res_config_settings.py @@ -6,56 +6,147 @@ from odoo import fields,api, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' + # Sidebar Menu Enable Setting sidebar_menu_enable = fields.Boolean( config_parameter='odex_sidebar_backend_theme2.sidebar_menu_enable', string='Enable Sidebar Menu', help='Enable or disable the sidebar menu in the backend' ) + # Navigation Menu Section Disable Setting disable_nav_menu_section = fields.Boolean( config_parameter='odex_sidebar_backend_theme2.disable_nav_menu_section', string='Disable Navigation Menu Section', help='Enable or disable the top navigation bar menu section in the backend interface' ) + # Sidebar Menu Icon Setting sidebar_menu_icon = fields.Binary( string="Sidebar Icon", help="Upload an icon for the sidebar menu.", ) + # Uncollapsed Sidebar Overlay Setting uncollapsed_sidebar_overlay = fields.Boolean( config_parameter='odex_sidebar_backend_theme2.uncollapsed_sidebar_overlay', string='Uncollapsed Sidebar Overlay', help='Enable overlay effect when sidebar is uncollapsed' ) - # set default value for the setting + # Sidebar Background Settings + sidebar_background_type = fields.Selection( + [('color', 'Color'), ('image', 'Image')], + config_parameter='odex_sidebar_backend_theme2.sidebar_background_type', + string='Sidebar Background Type', + default='color', + help='Choose the type of background for the sidebar' + ) + sidebar_background_color = fields.Char( + config_parameter='odex_sidebar_backend_theme2.sidebar_background_color', + default='#151a2d', + string='Sidebar Background Color', + help='Set the background color for the sidebar (hex code or color name)' + ) + sidebar_background_image = fields.Binary( + string='Sidebar Background Image', + help='Upload an image to use as the sidebar background' + ) + + # Sidebar Links Color Settings + sidebar_links_color = fields.Char( + config_parameter='odex_sidebar_backend_theme2.sidebar_links_color', + default='#ffffff', + string='Sidebar Links Color', + help='Set the color for the sidebar links (hex code or color name)' + ) + sidebar_links_hover_color = fields.Char( + config_parameter='odex_sidebar_backend_theme2.sidebar_links_hover_color', + default='#151a2d', + string='Sidebar Links Hover Color', + help='Set the hover color for the sidebar links (hex code or color name)' + ) + sidebar_links_active_color = fields.Char( + config_parameter='odex_sidebar_backend_theme2.sidebar_links_active_color', + default='#151a2d', + string='Sidebar Links Active Color', + help='Set the active color for the sidebar links (hex code or color name)' + ) + sidebar_links_bg_color = fields.Char( + config_parameter='odex_sidebar_backend_theme2.sidebar_links_bg_color', + default='#ffffff00', + string='Sidebar Links Background Color', + help='Set the background color for the sidebar links (hex code or color name)' + ) + sidebar_links_hover_bg_color = fields.Char( + config_parameter='odex_sidebar_backend_theme2.sidebar_links_hover_bg_color', + default='#151a2d', + string='Sidebar Links Hover Background Color', + help='Set the hover background color for the sidebar links (hex code or color name)' + ) + sidebar_links_active_bg_color = fields.Char( + config_parameter='odex_sidebar_backend_theme2.sidebar_links_active_bg_color', + default='#ffffff', + string='Sidebar Links Active Background Color', + help='Set the active background color for the sidebar links (hex code or color name)' + ) + sidebar_scrollbar_track_color = fields.Char( + config_parameter='odex_sidebar_backend_theme2.sidebar_scrollbar_track_color', + default='#2f3542', + string='Sidebar Scrollbar Track Color', + help='Set the color for the sidebar scrollbar track (hex code or color name)' + ) + sidebar_scrollbar_thumb_color = fields.Char( + config_parameter='odex_sidebar_backend_theme2.sidebar_scrollbar_thumb_color', + default='#151a2d', + string='Sidebar Scrollbar Thumb Color', + help='Set the color for the sidebar scrollbar thumb (hex code or color name)' + ) + sidebar_scrollbar_thumb_hover_color = fields.Char( + config_parameter='odex_sidebar_backend_theme2.sidebar_scrollbar_thumb_hover_color', + default='#151a2d', + string='Sidebar Scrollbar Thumb Hover Color', + help='Set the hover color for the sidebar scrollbar thumb (hex code or color name)' + ) + def get_values(self): res = super(ResConfigSettings, self).get_values() IrConfigParam = self.env['ir.config_parameter'].sudo() sidebar_menu_enable = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_menu_enable') disable_nav_menu_section = IrConfigParam.get_param('odex_sidebar_backend_theme2.disable_nav_menu_section') uncollapsed_sidebar_overlay = IrConfigParam.get_param('odex_sidebar_backend_theme2.uncollapsed_sidebar_overlay') + sidebar_background_type = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_background_type') + sidebar_background_color = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_background_color') + sidebar_background_image = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_background_image') + sidebar_links_color = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_links_color') + sidebar_links_hover_color = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_links_hover_color') + sidebar_links_active_color = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_links_active_color') + sidebar_links_bg_color = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_links_bg_color') + sidebar_links_hover_bg_color = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_links_hover_bg_color') + sidebar_links_active_bg_color = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_links_active_bg_color') + sidebar_scrollbar_track_color = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_scrollbar_track_color') + sidebar_scrollbar_thumb_color = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_scrollbar_thumb_color') + sidebar_scrollbar_thumb_hover_color = IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_scrollbar_thumb_hover_color') + res.update( sidebar_menu_enable=sidebar_menu_enable == 'True', disable_nav_menu_section=disable_nav_menu_section == 'True', sidebar_menu_icon=IrConfigParam.get_param('odex_sidebar_backend_theme2.sidebar_menu_icon'), uncollapsed_sidebar_overlay=uncollapsed_sidebar_overlay == 'True', + sidebar_background_type=sidebar_background_type or 'color', + sidebar_background_color=sidebar_background_color or '#151a2d', + sidebar_background_image=sidebar_background_image or False, + sidebar_links_color=sidebar_links_color or '#ffffff', + sidebar_links_hover_color=sidebar_links_hover_color or '#151a2d', + sidebar_links_active_color=sidebar_links_active_color or '#151a2d', + sidebar_links_bg_color=sidebar_links_bg_color or '#ffffff00', + sidebar_links_hover_bg_color=sidebar_links_hover_bg_color or '#151a2d', + sidebar_links_active_bg_color=sidebar_links_active_bg_color or '#ffffff', + sidebar_scrollbar_track_color=sidebar_scrollbar_track_color or '#2f3542', + sidebar_scrollbar_thumb_color=sidebar_scrollbar_thumb_color or '#151a2d', + sidebar_scrollbar_thumb_hover_color=sidebar_scrollbar_thumb_hover_color or '#151a2d', ) return res - def _generate_sidebar_css(self): - """Generate CSS rules for sidebar menu state""" - if self.disable_nav_menu_section: - return """ -.o_main_navbar .o_menu_sections { - display: none!important; - visibility: hidden!important; -} -""" - return "" - - # save the setting value def set_values(self): super(ResConfigSettings, self).set_values() IrConfigParam = self.env['ir.config_parameter'].sudo() @@ -75,7 +166,56 @@ class ResConfigSettings(models.TransientModel): 'odex_sidebar_backend_theme2.uncollapsed_sidebar_overlay', str(self.uncollapsed_sidebar_overlay) ) - + IrConfigParam.set_param( + 'odex_sidebar_backend_theme2.sidebar_background_type', + self.sidebar_background_type or 'color' + ) + IrConfigParam.set_param( + 'odex_sidebar_backend_theme2.sidebar_background_color', + self.sidebar_background_color or '#151a2d' + ) + IrConfigParam.set_param( + 'odex_sidebar_backend_theme2.sidebar_background_image', + self.sidebar_background_image or False + ) + IrConfigParam.set_param( + 'odex_sidebar_backend_theme2.sidebar_links_color', + self.sidebar_links_color or '#ffffff' + ) + IrConfigParam.set_param( + 'odex_sidebar_backend_theme2.sidebar_links_hover_color', + self.sidebar_links_hover_color or '#151a2d' + ) + IrConfigParam.set_param( + 'odex_sidebar_backend_theme2.sidebar_links_active_color', + self.sidebar_links_active_color or '#151a2d' + ) + IrConfigParam.set_param( + 'odex_sidebar_backend_theme2.sidebar_links_bg_color', + self.sidebar_links_bg_color or '#ffffff00' + ) + IrConfigParam.set_param( + 'odex_sidebar_backend_theme2.sidebar_links_hover_bg_color', + self.sidebar_links_hover_bg_color or '#151a2d' + ) + IrConfigParam.set_param( + 'odex_sidebar_backend_theme2.sidebar_links_active_bg_color', + self.sidebar_links_active_bg_color or '#ffffff' + ) + IrConfigParam.set_param( + 'odex_sidebar_backend_theme2.sidebar_scrollbar_track_color', + self.sidebar_scrollbar_track_color or '#2f3542' + ) + IrConfigParam.set_param( + 'odex_sidebar_backend_theme2.sidebar_scrollbar_thumb_color', + self.sidebar_scrollbar_thumb_color or '#151a2d' + ) + IrConfigParam.set_param( + 'odex_sidebar_backend_theme2.sidebar_scrollbar_thumb_hover_color', + self.sidebar_scrollbar_thumb_hover_color or '#151a2d' + ) + + # Store sidebar menu icon URL if self.sidebar_menu_icon: # Store the image URL in config parameter image_url = f"/web/image/res.config.settings/{self.id}/sidebar_menu_icon" @@ -92,6 +232,32 @@ class ResConfigSettings(models.TransientModel): return True + def _generate_sidebar_css(self): + """Generate CSS rules for sidebar menu state""" + css = f""" +/* Sidebar Menu State CSS */ +:root {{ + --ox-sidebar-bg-color: {self.sidebar_background_color}; + --ox-sidebar-links-color: {self.sidebar_links_color}; + --ox-sidebar-links-hover-color: {self.sidebar_links_hover_color}; + --ox-sidebar-links-active-color: {self.sidebar_links_active_color}; + --ox-sidebar-links-bg-color: {self.sidebar_links_bg_color}; + --ox-sidebar-links-hover-bg-color: {self.sidebar_links_hover_bg_color}; + --ox-sidebar-links-active-bg-color: {self.sidebar_links_active_bg_color}; + --ox-sidebar-scrollbar-track-color: {self.sidebar_scrollbar_track_color}; + --ox-sidebar-scrollbar-thumb-color: {self.sidebar_scrollbar_thumb_color}; + --ox-sidebar-scrollbar-thumb-hover-color: {self.sidebar_scrollbar_thumb_hover_color}; +}} +""" + if self.disable_nav_menu_section: + css += """ +.o_main_navbar .o_menu_sections { + display: none!important; + visibility: hidden!important; +} +""" + return css + @api.model def get_sidebar_setting(self): IrConfigParam = self.env['ir.config_parameter'].sudo() diff --git a/odex30_base/odex_sidebar_backend_theme2/static/src/scss/sidebar_menu.scss b/odex30_base/odex_sidebar_backend_theme2/static/src/scss/sidebar_menu.scss index e5fd256..f0bc36b 100644 --- a/odex30_base/odex_sidebar_backend_theme2/static/src/scss/sidebar_menu.scss +++ b/odex30_base/odex_sidebar_backend_theme2/static/src/scss/sidebar_menu.scss @@ -2,455 +2,456 @@ 1. Main Sidebar Design =================================== */ .custom_sidebar { - display: flex; - flex-direction: column; - position: fixed; - top: 0; - left: 0; - width: 270px; - height: 100vh; - overflow: auto; - background-color: #151a2d; - z-index: 999; - transform: translateX(0%); - transition: all 0.4s ease-in-out; + display: flex; + flex-direction: column; + position: fixed; + top: 0; + left: 0; + width: 270px; + height: 100vh; + overflow: auto; + background-color: var(--ox-sidebar-bg-color, #151a2d); + z-index: 999; + transform: translateX(0%); + transition: all 0.4s ease-in-out; - &:not(.is-open) { - transform: translateX(-100%) !important; - /* Use !important to force hiding */ - } - - /* =============== Add New Flyout =============== */ - - &.is-collapsed { - overflow: visible; - - li { - position: relative; - z-index: 1000; + &:not(.is-open) { + transform: translateX(-100%) !important; + /* Use !important to force hiding */ } - .flyout-panel { - display: none; - position: absolute; - left: 100%; - top: 0; - min-width: 220px; - background: #151a2d; - color: #fff; - border-radius: 10px; - padding: 10px; - box-shadow: 0 12px 30px rgba(8, 10, 20, 0.6); - transform-origin: left top; - transition: opacity 180ms ease, transform 180ms ease; - opacity: 0; - transform: translateX(-6px) scale(0.98); - pointer-events: none; + /* =============== Add New Flyout =============== */ + + &.is-collapsed { + overflow: visible; + + li { + position: relative; + z-index: 1000; + } + + .flyout-panel { + display: none; + position: absolute; + left: 100%; + top: 0; + min-width: 220px; + background: var(--ox-sidebar-bg-color, #151a2d); + color: #fff; + border-radius: 10px; + padding: 10px; + box-shadow: 0 12px 30px rgba(8, 10, 20, 0.6); + transform-origin: left top; + transition: opacity 180ms ease, transform 180ms ease; + opacity: 0; + transform: translateX(-6px) scale(0.98); + pointer-events: none; + } + + li:hover>.flyout-panel { + display: block; + opacity: 1; + transform: translateX(0) scale(1); + pointer-events: auto; + } + + .flyout-list { + list-style: none; + padding: 6px 4px; + display: flex; + flex-direction: column; + gap: 6px; + } + + .flyout-item { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 10px; + border-radius: 8px; + cursor: pointer; + transition: background 150ms ease; + white-space: nowrap; + } + + .flyout-item:hover { + background: rgba(255, 255, 255, 0.05); + } + + .flyout-item .icon { + width: 28px; + height: 28px; + display: flex; + align-items: center; + justify-content: center; + } + + .flyout-item .label { + color: #fff; + font-size: 0.95rem; + } + + /* Submenu flyout */ + .flyout-item.has-children { + position: relative; + } + + .flyout-subpanel { + display: none; + position: absolute; + left: 100%; + top: 0; + min-width: 200px; + background: #151a2d; + border-radius: 10px; + padding: 10px; + box-shadow: 0 12px 30px rgba(8, 10, 20, 0.6); + opacity: 0; + transform: translateX(-6px) scale(0.98); + transition: opacity 180ms ease, transform 180ms ease; + pointer-events: none; + z-index: 1200; + } + + .flyout-item.has-children:hover>.flyout-subpanel { + display: block; + opacity: 1; + transform: translateX(0) scale(1); + pointer-events: auto; + } } - li:hover > .flyout-panel { - display: block; - opacity: 1; - transform: translateX(0) scale(1); - pointer-events: auto; + &.is-collapsed { + width: 90px; + transform: translateX(0); + + .sidebar-header { + padding: 25px 10px; + justify-content: center; + flex-direction: column; + + .header-logo { + img { + width: 46px; + height: 46px; + } + } + + .sidebar-toggler { + position: static; + width: 50%; + margin-top: 25px; + } + } + + .sidebar-nav { + .sidebar_menu_list { + padding: 0 8px; + + &.primary-nav { + + .has-children, + li:not(.has-children) { + position: relative; + + .menu-item-container { + padding: 11px 8px; + justify-content: center; + + .menu-item-icon { + margin: 0; + width: 30px; + height: 30px; + } + + .menu-item-link { + display: none; + } + + .toggle-icon { + display: none; + } + + &:hover { + background-color: #eef2ff; + color: #151a2d; + } + + &:active { + background-color: #d9e1fd; + transform: scale(0.95); + } + } + } + + .submenu_list { + display: none; + } + } + + &.secondary-nav { + width: auto; + bottom: 20px; + left: 0; + right: 0; + padding: 0 8px; + + .nav-item { + position: relative; + z-index: 1000; + + .nav-link { + padding: 11px 8px; + justify-content: center; + + .nav-label { + display: none; + } + + .nav_icon { + margin: 0; + } + } + + .dropdown_menu { + display: none; + } + + // Flyout support for secondary-nav + &:hover>.flyout-panel { + display: block; + opacity: 1; + transform: translateX(0) scale(1); + pointer-events: auto; + } + } + } + } + } } - .flyout-list { - list-style: none; - padding: 6px 4px; - display: flex; - flex-direction: column; - gap: 6px; + li.open { + >.menu-item-container { + background-color: #fff; + + .menu-item-link { + color: #151a2d !important; + } + + .toggle-icon { + transform: rotate(90deg); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e"); + } + } } - .flyout-item { - display: flex; - align-items: center; - gap: 10px; - padding: 8px 10px; - border-radius: 8px; - cursor: pointer; - transition: background 150ms ease; - white-space: nowrap; + &::-webkit-scrollbar { + width: 8px; } - .flyout-item:hover { - background: rgba(255, 255, 255, 0.05); + &::-webkit-scrollbar-track { + background: var(--ox-sidebar-scrollbar-track-color, #0e1223); } - .flyout-item .icon { - width: 28px; - height: 28px; - display: flex; - align-items: center; - justify-content: center; + &::-webkit-scrollbar-thumb { + background-color: var(--ox-sidebar-scrollbar-thumb-color, #151a2d); + border-radius: 4px; } - .flyout-item .label { - color: #fff; - font-size: 0.95rem; + &::-webkit-scrollbar-thumb:hover { + background-color: var(--ox-sidebar-scrollbar-thumb-hover-color, #151a2d); } - /* Submenu flyout */ - .flyout-item.has-children { - position: relative; - } - - .flyout-subpanel { - display: none; - position: absolute; - left: 100%; - top: 0; - min-width: 200px; - background: #151a2d; - border-radius: 10px; - padding: 10px; - box-shadow: 0 12px 30px rgba(8, 10, 20, 0.6); - opacity: 0; - transform: translateX(-6px) scale(0.98); - transition: opacity 180ms ease, transform 180ms ease; - pointer-events: none; - z-index: 1200; - } - - .flyout-item.has-children:hover > .flyout-subpanel { - display: block; - opacity: 1; - transform: translateX(0) scale(1); - pointer-events: auto; - } - } - - &.is-collapsed { - width: 90px; - transform: translateX(0); - .sidebar-header { - padding: 25px 10px; - justify-content: center; - flex-direction: column; + display: flex; + position: relative; + padding: 25px 20px; + align-items: center; + justify-content: space-between; - .header-logo { - img { - width: 46px; - height: 46px; + .header-logo { + img { + width: 46px; + height: 46px; + display: block; + object-fit: contain; + border-radius: 50%; + } } - } - .sidebar-toggler { - position: static; - width: 50%; - margin-top: 25px; - } + .sidebar-toggler { + position: absolute; + right: 20px; + height: 35px; + width: 35px; + color: #151a2d; + border: none; + cursor: pointer; + display: flex; + background: #eef2ff; + align-items: center; + justify-content: center; + border-radius: 8px; + transition: 0.4s ease; + + &:hover { + background: #d9e1fd; + } + + span { + transition: 0.4s ease; + } + + i { + font-size: 18px; + transition: transform 0.4s ease; + } + } } .sidebar-nav { - .sidebar_menu_list { - padding: 0 8px; + flex: 1; + display: flex; + flex-direction: column; - &.primary-nav { - - .has-children, - li:not(.has-children) { - position: relative; - - .menu-item-container { - padding: 11px 8px; - justify-content: center; - - .menu-item-icon { - margin: 0; - width: 30px; - height: 30px; - } - - .menu-item-link { - display: none; - } - - .toggle-icon { - display: none; - } - - &:hover { - background-color: #eef2ff; - color: #151a2d; - } - - &:active { - background-color: #d9e1fd; - transform: scale(0.95); - } - } - } - - .submenu_list { - display: none; - } - } - - &.secondary-nav { - width: auto; - bottom: 20px; - left: 0; - right: 0; - padding: 0 8px; - - .nav-item { - position: relative; - z-index: 1000; - - .nav-link { - padding: 11px 8px; - justify-content: center; - - .nav-label { - display: none; - } - - .nav_icon { - margin: 0; - } - } - - .dropdown_menu { - display: none; - } - - // Flyout support for secondary-nav - &:hover > .flyout-panel { - display: block; - opacity: 1; - transform: translateX(0) scale(1); - pointer-events: auto; - } - } - } - } - } - } - - li.open { - > .menu-item-container { - background-color: #fff; - - .menu-item-link { - color: #151a2d !important; - } - - .toggle-icon { - transform: rotate(90deg); - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e"); - } - } - } - - &::-webkit-scrollbar { - width: 8px; - } - - &::-webkit-scrollbar-track { - background: #2f3542; - } - - &::-webkit-scrollbar-thumb { - background-color: #151a2d; - border-radius: 4px; - } - - &::-webkit-scrollbar-thumb:hover { - background-color: #151a2d; - } - - .sidebar-header { - display: flex; - position: relative; - padding: 25px 20px; - align-items: center; - justify-content: space-between; - - .header-logo { - img { - width: 46px; - height: 46px; - display: block; - object-fit: contain; - border-radius: 50%; - } - } - - .sidebar-toggler { - position: absolute; - right: 20px; - height: 35px; - width: 35px; - color: #151a2d; - border: none; - cursor: pointer; - display: flex; - background: #eef2ff; - align-items: center; - justify-content: center; - border-radius: 8px; - transition: 0.4s ease; - - &:hover { - background: #d9e1fd; - } - - span { - transition: 0.4s ease; - } - - i { - font-size: 18px; - transition: transform 0.4s ease; - } - } - } - - .sidebar-nav { - flex: 1; - display: flex; - flex-direction: column; - - .sidebar_menu_list { - list-style: none; - display: flex; - gap: 4px; - padding: 0 15px; - flex-direction: column; - transform: translateY(15px); - transition: 0.4s ease; - - &.primary-nav { - .has-children, - li:not(.has-children) { - &:hover { - > .menu-item-container { - background-color: #eef2ff; - - .menu-item-link { - color: #151a2d; - } - } - } - - .menu-item-container { + .sidebar_menu_list { + list-style: none; display: flex; - gap: 12px; - align-items: center; - justify-content: space-between; - cursor: pointer; - transition: all 0.3s; - border: 1px solid #151a2d; - text-decoration: none; - padding: 11px 15px; - border-radius: 8px; - white-space: nowrap; - - // image icon style - .menu-item-icon { - width: 25px; - height: 25px; - margin: 0 10px; - object-fit: contain; - } - - // name style - .menu-item-link { - color: #fff; - flex-grow: 1; - font-size: 1rem; - text-decoration: none; - transition: opacity 0.3s ease; - } - - // toggle icon style - .toggle-icon { - width: 20px; - height: 20px; - margin-right: 10px; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23b9d0ec' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: center; - transition: transform 0.2s ease-in-out; - } - } - } - - .submenu_list { - list-style: none; - padding: 5px 0; - - li { - .menu-item-container { - margin-left: 8px; - border: 1px solid transparent; - transition: all 0.2s ease; - - &:hover { - background-color: #eef2ff; - border-color: #151a2d; - - .menu-item-link { - color: #151a2d; - } - } - } - } - } - } - - &.secondary-nav { - margin-top: auto; - // width: calc(100% - 30px); - background: #151a2d; - padding: 20px 15px; - - .nav-item { - position: relative; - // margin: 0 15px; - - &:hover > .nav-link { - color: #151a2d !important; - background-color: #eef2ff; - } - - .nav-link { - color: #fff !important; - display: flex; - gap: 12px; - white-space: nowrap; - border-radius: 8px; - padding: 11px 15px; - align-items: center; - text-decoration: none; - border: 1px solid #151a2d; + gap: 4px; + padding: 0 15px; + flex-direction: column; + transform: translateY(15px); transition: 0.4s ease; - .nav_icon { - font-size: 24px; - margin: 0 10px; + &.primary-nav { + + .has-children, + li:not(.has-children) { + &:hover { + >.menu-item-container { + background-color: var(--ox-sidebar-links-hover-bg-color, #eef2ff); + + .menu-item-link { + color: var(--ox-sidebar-links-hover-color, #151a2d); + } + } + } + + .menu-item-container { + display: flex; + gap: 12px; + align-items: center; + justify-content: space-between; + cursor: pointer; + transition: all 0.3s; + border: 1px solid transparent; + text-decoration: none; + padding: 11px 15px; + border-radius: 8px; + white-space: nowrap; + + // image icon style + .menu-item-icon { + width: 25px; + height: 25px; + margin: 0 10px; + object-fit: contain; + } + + // name style + .menu-item-link { + color: #fff; + flex-grow: 1; + font-size: 1rem; + text-decoration: none; + transition: opacity 0.3s ease; + } + + // toggle icon style + .toggle-icon { + width: 20px; + height: 20px; + margin-right: 10px; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23b9d0ec' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: center; + transition: transform 0.2s ease-in-out; + } + } + } + + .submenu_list { + list-style: none; + padding: 5px 0; + + li { + .menu-item-container { + margin-left: 8px; + border: 1px solid transparent; + transition: all 0.2s ease; + + &:hover { + background-color: var(--ox-sidebar-links-hover-bg-color, #eef2ff); + // border-color: #151a2d; + + .menu-item-link { + color: var(--ox-sidebar-links-hover-color, #151a2d); + } + } + } + } + } } - .nav-label { - font-size: 1rem; - transition: opacity 0.3s ease; - } - } + &.secondary-nav { + margin-top: auto; + // width: calc(100% - 30px); + background: var(--ox-sidebar-bg-color, #151a2d); + padding: 20px 15px; - .dropdown_menu { - height: 0; - overflow-y: hidden; - list-style: none; - padding-left: 15px; - transition: height 0.4s ease; - } + .nav-item { + position: relative; + // margin: 0 15px; + + &:hover>.nav-link { + color: var(--ox-sidebar-links-hover-color, #151a2d) !important; + background-color: var(--ox-sidebar-links-hover-bg-color, #eef2ff); + } + + .nav-link { + color: #fff !important; + display: flex; + gap: 12px; + white-space: nowrap; + border-radius: 8px; + padding: 11px 15px; + align-items: center; + text-decoration: none; + border: 1px solid transparent; + transition: 0.4s ease; + + .nav_icon { + font-size: 24px; + margin: 0 10px; + } + + .nav-label { + font-size: 1rem; + transition: opacity 0.3s ease; + } + } + + .dropdown_menu { + height: 0; + overflow-y: hidden; + list-style: none; + padding-left: 15px; + transition: height 0.4s ease; + } + } + } } - } } - } } /* =================================== @@ -458,32 +459,32 @@ =================================== */ // Hide default application icon from top bar .o_navbar .o_main_navbar .o_navbar_apps_menu .o-dropdown { - display: none !important; + display: none !important; } .o_web_client { - margin-left: 0 !important; - transition: all 0.3s ease-in-out; + margin-left: 0 !important; + transition: all 0.3s ease-in-out; } /* Adjust Top Bar and Main Content */ .o_navbar, .o_action_manager { - transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; } /* Open Icon Design (New) */ .sidebar_toggle_icon { - position: relative; - display: flex; - align-items: center; - width: auto; - height: calc(var(--o-navbar-height) - 0px); - border-radius: 0; - user-select: none; - background: transparent; - color: var(--NavBar-entry-color, rgba(255, 255, 255, 0.9)); - font-size: 1.2em; - padding: 0 15px; - border: none; + position: relative; + display: flex; + align-items: center; + width: auto; + height: calc(var(--o-navbar-height) - 0px); + border-radius: 0; + user-select: none; + background: transparent; + color: var(--NavBar-entry-color, rgba(255, 255, 255, 0.9)); + font-size: 1.2em; + padding: 0 15px; + border: none; } \ No newline at end of file diff --git a/odex30_base/odex_sidebar_backend_theme2/views/res_config_settings.xml b/odex30_base/odex_sidebar_backend_theme2/views/res_config_settings.xml index 7136d9b..410e513 100644 --- a/odex30_base/odex_sidebar_backend_theme2/views/res_config_settings.xml +++ b/odex30_base/odex_sidebar_backend_theme2/views/res_config_settings.xml @@ -12,18 +12,36 @@ - + + options="{'size': [128, 128]}" /> + + + + + + + + + + + + + + + +