mirror of
https://gitlab.com/flectra-hq/flectra.git
synced 2026-10-25 23:40:05 -05:00
Merge branch 'feature/sidebarmenu' into 'master'
Sidebar Menu Optimizations See merge request flectra-hq/flectra!592
This commit is contained in:
commit
b3b3296895
5 files changed
+427
-313
No files matched your search
@@ -2,13 +2,32 @@ flectra.define('web_flectra.Menu', function (require) {
|
||||
"use strict";
|
||||
|
||||
var Menu = require('web.Menu');
|
||||
var SlideMenu = require('web_flectra.sidemenu');
|
||||
var config = require('web.config');
|
||||
|
||||
return Menu.include({
|
||||
start: function () {
|
||||
updateSidebar: function () {
|
||||
var btn = $('.o-menu-slide');
|
||||
var $fLauncherContent = $('.f_launcher_content');
|
||||
if (!$fLauncherContent.length || window.matchMedia('(max-device-width: 1024px)').matches) {
|
||||
btn.hide();
|
||||
$fLauncherContent.removeClass('mobile_views_menu_force');
|
||||
} else {
|
||||
btn.show();
|
||||
}
|
||||
if ($fLauncherContent.hasClass('mobile_views_menu_force') || window.matchMedia('(max-device-width: 1024px)').matches) {
|
||||
$('.f_launcher_content .app_name, .more-less, .oe_secondary_menu').addClass('hidden');
|
||||
$fLauncherContent.addClass('mobile_views_menu');
|
||||
$('.o_action_manager').addClass('force_mobile');
|
||||
} else {
|
||||
$('.f_launcher_content .app_name, .more-less, .oe_secondary_menu').removeClass('hidden');
|
||||
$fLauncherContent.removeClass('mobile_views_menu');
|
||||
$('.o_action_manager').removeClass('force_mobile');
|
||||
}
|
||||
}, start: function () {
|
||||
var self = this;
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
if(config.device.isMobile == true){
|
||||
if (config.device.isMobile == true) {
|
||||
self.$section_placeholder.addClass('mobile-view');
|
||||
self.$menu_brand_placeholder.addClass('mobile-view');
|
||||
}
|
||||
@@ -16,6 +35,16 @@ flectra.define('web_flectra.Menu', function (require) {
|
||||
self.$('.o_menu_systray').find('.dropdown-menu').on('click', function (ev) {
|
||||
self._appsMenu._onOpenCloseDashboard(true);
|
||||
});
|
||||
|
||||
$('.o-menu-slide').on('click', function (ev) {
|
||||
ev.preventDefault();
|
||||
$('.o-menu-slide > i').toggleClass('fa-compress fa-expand');
|
||||
$('.f_launcher_content').toggleClass('mobile_views_menu_force');
|
||||
self.updateSidebar();
|
||||
});
|
||||
$(window).on('resize', function (ev) {
|
||||
self.updateSidebar();
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,291 +1,339 @@
|
||||
flectra.define('web_flectra.sidemenu', function (require) {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var session = require('web.session');
|
||||
var Widget = require('web.Widget');
|
||||
var config = require('web.config');
|
||||
var rpc = require('web.rpc');
|
||||
var core = require('web.core');
|
||||
var session = require('web.session');
|
||||
var Widget = require('web.Widget');
|
||||
var config = require('web.config');
|
||||
var rpc = require('web.rpc');
|
||||
|
||||
var SideMenu = Widget.extend({
|
||||
init: function(menu_data) {
|
||||
this._super.apply(this, arguments);
|
||||
this.is_bound = $.Deferred();
|
||||
this._isMainMenuClick = false;
|
||||
this.isLoadflag = true;
|
||||
this.menu_data = menu_data;
|
||||
},
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$el = $('.f_launcher').find('.oe_application_menu_placeholder');
|
||||
return this.bind_menu();
|
||||
},
|
||||
do_reload: function() {
|
||||
var self = this;
|
||||
self.bind_menu();
|
||||
},
|
||||
bind_menu: function() {
|
||||
var self = this;
|
||||
this.$secondary_menus = this.$el.parents().find('.f_launcher');
|
||||
this.$secondary_menus.on('click', 'a[data-menu]', this.on_menu_click);
|
||||
this.$el.on('click', 'a[data-menu]', function (event) {
|
||||
event.preventDefault();
|
||||
var menu_id = $(event.currentTarget).data('menu');
|
||||
core.bus.trigger('change_menu_section', menu_id);
|
||||
});
|
||||
var activeMenu;
|
||||
|
||||
function toggleIcon(e) {
|
||||
$(e.target).prev().find('.more-less i').toggleClass('fa-chevron-down fa-chevron-right');
|
||||
}
|
||||
var SideMenu = Widget.extend({
|
||||
init: function (menu_data) {
|
||||
this._super.apply(this, arguments);
|
||||
this.is_bound = $.Deferred();
|
||||
this._isMainMenuClick = false;
|
||||
this.isLoadflag = true;
|
||||
this.menu_data = menu_data;
|
||||
},
|
||||
start: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.$el = $('.f_launcher').find('.oe_application_menu_placeholder');
|
||||
return this.bind_menu();
|
||||
},
|
||||
do_reload: function () {
|
||||
var self = this;
|
||||
self.bind_menu();
|
||||
},
|
||||
bind_menu: function () {
|
||||
var self = this;
|
||||
this.$secondary_menus = this.$el.parents().find('.f_launcher');
|
||||
this.$secondary_menus.on('click', 'a[data-menu]', this.on_menu_click);
|
||||
this.$el.on('click', 'a[data-menu]', function (event) {
|
||||
event.preventDefault();
|
||||
var menu_id = $(event.currentTarget).data('menu');
|
||||
core.bus.trigger('change_menu_section', menu_id);
|
||||
});
|
||||
|
||||
function toggleCollapse(e) {
|
||||
$('.f_launcher .oe_secondary_menu.show').not(e.target).collapse('toggle');
|
||||
}
|
||||
|
||||
function closeFullMenu(e) {
|
||||
$('.f_launcher_content .app_name, .more-less, .oe_secondary_menu').addClass('hidden');
|
||||
$('.f_launcher_content').addClass('mobile_views_menu');
|
||||
}
|
||||
|
||||
function openFullMenu(e) {
|
||||
$('.f_launcher_content .app_name, .more-less, .oe_secondary_menu').removeClass('hidden');
|
||||
$('.f_launcher_content').removeClass('mobile_views_menu');
|
||||
}
|
||||
|
||||
this.$secondary_menus.find('[data-toggle="tooltip"]').tooltip({
|
||||
trigger: "hover",
|
||||
delay: 500
|
||||
});
|
||||
|
||||
this.$secondary_menus.find('#menu_launcher')
|
||||
.on('hidden.bs.collapse', toggleIcon)
|
||||
.on('shown.bs.collapse', toggleIcon)
|
||||
.on('shown.bs.collapse', toggleCollapse);
|
||||
|
||||
// Hide menu on mouseleave and show menu on mouseover
|
||||
$('.f_launcher_content')
|
||||
.on('mouseleave', closeFullMenu)
|
||||
.on('mouseover', openFullMenu);
|
||||
|
||||
// Enable touch gestures for mobile devices
|
||||
$(".f_launcher_content").swipe({
|
||||
swipeLeft:closeFullMenu,
|
||||
swipeRight:openFullMenu,
|
||||
});
|
||||
|
||||
// Hide elements on init as default
|
||||
if ($('.f_launcher_content').hasClass('mobile_views_menu')) {
|
||||
closeFullMenu();
|
||||
}
|
||||
|
||||
// Hide second level submenus
|
||||
this.$secondary_menus.find('.oe_menu_toggler').siblings('.oe_secondary_submenu').addClass('o_hidden');
|
||||
if (self.current_menu) {
|
||||
self.open_menu(self.current_menu);
|
||||
}
|
||||
this.is_bound.resolve();
|
||||
},
|
||||
|
||||
/**
|
||||
* Highlights the active menu record
|
||||
* collapse the menus and set the arrows in right direction.
|
||||
*
|
||||
* @param {Number} action id of the menu entry to select
|
||||
*/
|
||||
set_menu: function (app) {
|
||||
if (!app.actionID || !app.menuID) {
|
||||
return;
|
||||
}
|
||||
var $main_menu = $('.f_launcher_content');
|
||||
var $clicked_menu = $main_menu.find('a[data-menu=' + app.menuID + ']');
|
||||
var $main_menu_container = $clicked_menu.closest('li.panel');
|
||||
var $main_menu_chevron = $main_menu_container.find('i');
|
||||
var $secondary_menu = $main_menu_container.find('.oe_secondary_menu');
|
||||
|
||||
$secondary_menu.collapse('toggle');
|
||||
$clicked_menu.closest('li:not(".panel")').addClass('active');
|
||||
|
||||
/** If triggered a menu change from APP DASHBOARD use actionID instead. **/
|
||||
if ($clicked_menu.length > 1) {
|
||||
var $active_menu = $main_menu.find('a.oe_menu_leaf[data-action-id=' + app.actionID + ']').closest('li:not(".panel")');
|
||||
$active_menu.addClass('active');
|
||||
} else {
|
||||
var $active_menu = $main_menu.find('a.oe_menu_leaf[data-action-id=' + app.actionID + ']').closest('.oe_secondary_menu_section');
|
||||
$active_menu.addClass('active');
|
||||
}
|
||||
$clicked_menu.closest('.panel').addClass('active')
|
||||
|
||||
/** Open secondary submenus. **/
|
||||
var $secondary_menu_parents = $clicked_menu.parents('.oe_secondary_submenu');
|
||||
var $secondary_menu_toggler = $clicked_menu.closest('li:not(".active")').children('.oe_menu_toggler')
|
||||
if ($secondary_menu_parents.length > 1) {
|
||||
setTimeout(function () {
|
||||
$secondary_menu_toggler.addClass('oe_menu_opened');
|
||||
$clicked_menu.closest('ul').removeClass('o_hidden');
|
||||
}, 2000);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets all highlighted menu entries and
|
||||
* collapse all opened menu items.
|
||||
*/
|
||||
reset_menu: function () {
|
||||
var $main_menu = $('.f_launcher_content');
|
||||
var $main_menu_container = $main_menu.find('.collapse.show');
|
||||
var $active_entry = $main_menu.find('li.active');
|
||||
var $chevron_down = $main_menu.find('.fa-chevron-down');
|
||||
var $secondary_menu_link = $main_menu.find('.oe_menu_opened');
|
||||
var $secondary_menu_container = $main_menu.find('.oe_secondary_menu > .oe_secondary_submenu > li > .oe_secondary_submenu')
|
||||
|
||||
$main_menu_container.removeClass('show');
|
||||
$active_entry.removeClass('active');
|
||||
$chevron_down.removeClass('fa-chevron-down').addClass('fa-chevron-right');
|
||||
$secondary_menu_link.removeClass('oe_menu_opened');
|
||||
$secondary_menu_container.addClass('o_hidden');
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens a given menu by id, as if a user had browsed to that menu by hand
|
||||
* except does not trigger any event on the way
|
||||
*
|
||||
* @param {Number} id database id of the terminal menu to select
|
||||
*/
|
||||
open_menu: function (id) {
|
||||
var self = this;
|
||||
this.current_menu = id;
|
||||
session.active_id = id;
|
||||
var $clicked_menu, $sub_menu, $main_menu;
|
||||
$clicked_menu = this.$el.add(this.$secondary_menus).find('a[data-menu=' + id + ']');
|
||||
this.trigger('open_menu', id, $clicked_menu);
|
||||
|
||||
if (this.$secondary_menus.has($clicked_menu).length) {
|
||||
$sub_menu = $clicked_menu.parents('.oe_secondary_menu');
|
||||
$main_menu = this.$el.find('a[data-menu=' + $sub_menu.data('menu-parent') + ']');
|
||||
} else {
|
||||
$sub_menu = this.$secondary_menus.find('.oe_secondary_menu[data-menu-parent=' + $clicked_menu.attr('data-menu') + ']');
|
||||
$main_menu = $clicked_menu;
|
||||
}
|
||||
|
||||
// Activate current main menu
|
||||
this.$el.find('.active').removeClass('active');
|
||||
$main_menu.parent().addClass('active');
|
||||
|
||||
var isNotMainMenu = $clicked_menu.hasClass('oe_main_menu');
|
||||
if(this._isMainMenuClick || this.isLoadflag && isNotMainMenu) {
|
||||
var href_id = $sub_menu.attr('id');
|
||||
if (href_id && $sub_menu.attr('class').indexOf('in') === -1) {
|
||||
this.$secondary_menus.find("a[href='#" + href_id + "']").trigger('click');
|
||||
this.$secondary_menus.find("a[href='#" + href_id + " i']")
|
||||
.addClass('fa-chevron-right')
|
||||
.removeClass('fa-chevron-down');
|
||||
} else {
|
||||
$clicked_menu.parents('li.panel').find('.oe_main_menu_container .more-less a').trigger('click');
|
||||
this.$secondary_menus.find("a[href='#" + href_id + " i']")
|
||||
.addClass('fa-chevron-down')
|
||||
.removeClass('fa-chevron-right');
|
||||
function toggleIcon(e) {
|
||||
$(e.target).prev().find('.more-less i').toggleClass('fa-chevron-down fa-chevron-right');
|
||||
}
|
||||
}
|
||||
|
||||
// Hide/Show the leftbar menu depending of the presence of sub-items
|
||||
this.$secondary_menus.toggleClass('o_hidden', !$sub_menu.children().length);
|
||||
function toggleCollapse(e) {
|
||||
$('.f_launcher .oe_secondary_menu.show').not(e.target).collapse('toggle')
|
||||
let $activeMenu = $('.oe_main_menu_container.active');
|
||||
if ($activeMenu.length && !$activeMenu.is(activeMenu)) {
|
||||
activeMenu = $activeMenu;
|
||||
setTimeout(() => {
|
||||
// $('.f_launcher').scrollTop(0);
|
||||
let $main = $('.f_launcher');
|
||||
let scrollTop = $activeMenu.offset().top;
|
||||
$('.f_launcher').animate({
|
||||
scrollTop: scrollTop - ($main.offset().top - $main.scrollTop())
|
||||
});
|
||||
}, 400);
|
||||
|
||||
// Activate current menu item and show parents
|
||||
this.$secondary_menus.find('.active').removeClass('active');
|
||||
if ($main_menu !== $clicked_menu) {
|
||||
$clicked_menu.parents().removeClass('o_hidden');
|
||||
if ($clicked_menu.is('.oe_menu_toggler')) {
|
||||
$clicked_menu.toggleClass('oe_menu_opened').siblings('.oe_secondary_submenu:first').toggleClass('o_hidden');
|
||||
} else {
|
||||
$clicked_menu.parent().addClass('active');
|
||||
}
|
||||
this.$secondary_menus.find('.oe_main_menu_container').removeClass('active');
|
||||
$clicked_menu.parents('li.panel').find('.oe_main_menu_container').addClass('active');
|
||||
}
|
||||
$clicked_menu.closest('.panel').addClass('active')
|
||||
// add a tooltip to cropped menu items
|
||||
this.$secondary_menus.find('.oe_secondary_submenu li a span').each(function() {
|
||||
$(this).tooltip(this.scrollWidth > this.clientWidth ? {title: $(this).text().trim(), placement: 'right'} :'dispose');
|
||||
});
|
||||
this.isLoadflag = false;
|
||||
},
|
||||
/**
|
||||
* Call open_menu on a menu_item that matches the action_id
|
||||
*
|
||||
* If `menuID` is a match on this action, open this menu_item.
|
||||
* Otherwise open the first menu_item that matches the action_id.
|
||||
*
|
||||
* @param {Number} id the action_id to match
|
||||
* @param {Number} [menuID] a menu ID that may match with provided action
|
||||
*/
|
||||
open_action: function (id, menuID) {
|
||||
var $menu = this.$el.add(this.$secondary_menus).find('a[data-action-id="' + id + '"]');
|
||||
if (!(menuID && $menu.filter("[data-menu='" + menuID + "']").length)) {
|
||||
// menuID doesn't match action, so pick first menu_item
|
||||
menuID = $menu.data('menu');
|
||||
}
|
||||
if (menuID) {
|
||||
this.open_menu(menuID);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Process a click on a menu item
|
||||
*
|
||||
* @param {Number} id the menu_id
|
||||
*/
|
||||
menu_click: function(id) {
|
||||
if (!id) { return; }
|
||||
|
||||
// find back the menuitem in dom to get the action
|
||||
var $item = this.$el.find('a[data-menu=' + id + ']');
|
||||
if (!$item.length) {
|
||||
$item = this.$secondary_menus.find('a[data-menu=' + id + ']');
|
||||
}
|
||||
var action_id = $item.data('action-id');
|
||||
// If first level menu doesnt have action trigger first leaf
|
||||
if (!action_id) {
|
||||
if(this.$el.has($item).length) {
|
||||
var $sub_menu = this.$secondary_menus.find('.oe_secondary_menu[data-menu-parent=' + id + ']');
|
||||
var $items = $sub_menu.find('a[data-action-id]').filter('[data-action-id!=""]');
|
||||
if($items.length) {
|
||||
action_id = $items.data('action-id');
|
||||
id = $items.data('menu');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (action_id) {
|
||||
this.trigger_up('app_clicked', {
|
||||
action_id: action_id,
|
||||
menu_id: id,
|
||||
|
||||
function updateSlideButton(e) {
|
||||
var btn = $('.o-menu-slide');
|
||||
if (window.matchMedia('(max-device-width: 1024px)').matches) {
|
||||
btn.hide();
|
||||
} else {
|
||||
btn.show();
|
||||
}
|
||||
}
|
||||
|
||||
function closeFullMenu(e) {
|
||||
var $fLauncherContent = $('.f_launcher_content');
|
||||
if ($fLauncherContent.hasClass('mobile_views_menu_force') || window.matchMedia('(max-device-width: 1024px)').matches) {
|
||||
$('.f_launcher_content .app_name, .more-less, .oe_secondary_menu').addClass('hidden');
|
||||
$fLauncherContent.addClass('mobile_views_menu');
|
||||
} else {
|
||||
$fLauncherContent.removeClass('mobile_views_menu');
|
||||
}
|
||||
}
|
||||
|
||||
function openFullMenu(e) {
|
||||
var $fLauncherContent = $('.f_launcher_content');
|
||||
if ($fLauncherContent.hasClass('mobile_views_menu_force') || window.matchMedia('(max-device-width: 1024px)').matches) {
|
||||
$('.f_launcher_content .app_name, .more-less, .oe_secondary_menu').removeClass('hidden');
|
||||
$fLauncherContent.removeClass('mobile_views_menu');
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
function resizeFullMenu(e) {
|
||||
var $fLauncherContent = $('.f_launcher_content');
|
||||
if ($fLauncherContent.hasClass('mobile_views_menu_force') || window.matchMedia('(max-device-width: 1024px)').matches) {
|
||||
$('.f_launcher_content .app_name, .more-less, .oe_secondary_menu').addClass('hidden');
|
||||
$fLauncherContent.addClass('mobile_views_menu');
|
||||
} else {
|
||||
$('.f_launcher_content .app_name, .more-less, .oe_secondary_menu').removeClass('hidden');
|
||||
$fLauncherContent.removeClass('mobile_views_menu');
|
||||
}
|
||||
}
|
||||
|
||||
$(window).on('resize', resizeFullMenu);
|
||||
this.$secondary_menus.find('[data-toggle="tooltip"]').tooltip({
|
||||
trigger: "hover",
|
||||
delay: 500
|
||||
});
|
||||
} else {
|
||||
console.log('Menu no action found web test 04 will fail');
|
||||
}
|
||||
this._isActionId = action_id === undefined ? false : true;
|
||||
this.open_menu(id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Change the current top menu
|
||||
*
|
||||
* @param {int} [menu_id] the top menu id
|
||||
*/
|
||||
on_change_top_menu: function(menu_id) {
|
||||
var self = this;
|
||||
this.menu_click(menu_id);
|
||||
},
|
||||
on_menu_click: function(ev) {
|
||||
ev.preventDefault();
|
||||
if(!parseInt($(ev.currentTarget).data('menu'))) return;
|
||||
this._isMainMenuClick = $(ev.currentTarget).attr('class').indexOf('oe_main_menu') !== -1 ? true : false;
|
||||
this.menu_click($(ev.currentTarget).data('menu'));
|
||||
},
|
||||
this.$secondary_menus.find('#menu_launcher')
|
||||
.on('hidden.bs.collapse', toggleIcon)
|
||||
.on('shown.bs.collapse', toggleIcon)
|
||||
.on('shown.bs.collapse', toggleCollapse);
|
||||
|
||||
// Hide menu on mouseleave and show menu on mouseover
|
||||
$('.f_launcher_content')
|
||||
.on('mouseleave', closeFullMenu)
|
||||
.on('mouseover', openFullMenu);
|
||||
|
||||
// Enable touch gestures for mobile devices
|
||||
$(".f_launcher_content").swipe({
|
||||
swipeLeft: closeFullMenu,
|
||||
swipeRight: openFullMenu,
|
||||
});
|
||||
|
||||
// Hide elements on init as default
|
||||
if ($('.f_launcher_content').hasClass('mobile_views_menu')) {
|
||||
closeFullMenu();
|
||||
}
|
||||
|
||||
// Hide second level submenus
|
||||
this.$secondary_menus.find('.oe_menu_toggler').siblings('.oe_secondary_submenu').addClass('o_hidden');
|
||||
if (self.current_menu) {
|
||||
self.open_menu(self.current_menu);
|
||||
}
|
||||
updateSlideButton();
|
||||
this.is_bound.resolve();
|
||||
},
|
||||
|
||||
/**
|
||||
* Highlights the active menu record
|
||||
* collapse the menus and set the arrows in right direction.
|
||||
*
|
||||
* @param {Number} action id of the menu entry to select
|
||||
*/
|
||||
set_menu: function (app) {
|
||||
if (!app.actionID || !app.menuID) {
|
||||
return;
|
||||
}
|
||||
var $main_menu = $('.f_launcher_content');
|
||||
var $clicked_menu = $main_menu.find('a[data-menu=' + app.menuID + ']');
|
||||
var $main_menu_container = $clicked_menu.closest('li.panel');
|
||||
var $main_menu_chevron = $main_menu_container.find('i');
|
||||
var $secondary_menu = $main_menu_container.find('.oe_secondary_menu');
|
||||
|
||||
$secondary_menu.collapse('toggle');
|
||||
$clicked_menu.closest('li:not(".panel")').addClass('active');
|
||||
|
||||
/** If triggered a menu change from APP DASHBOARD use actionID instead. **/
|
||||
if ($clicked_menu.length > 1) {
|
||||
var $active_menu = $main_menu.find('a.oe_menu_leaf[data-action-id=' + app.actionID + ']').closest('li:not(".panel")');
|
||||
$active_menu.addClass('active');
|
||||
} else {
|
||||
var $active_menu = $main_menu.find('a.oe_menu_leaf[data-action-id=' + app.actionID + ']').closest('.oe_secondary_menu_section');
|
||||
$active_menu.addClass('active');
|
||||
}
|
||||
$clicked_menu.closest('.panel').addClass('active')
|
||||
|
||||
/** Open secondary submenus. **/
|
||||
var $secondary_menu_parents = $clicked_menu.parents('.oe_secondary_submenu');
|
||||
var $secondary_menu_toggler = $clicked_menu.closest('li:not(".active")').children('.oe_menu_toggler')
|
||||
if ($secondary_menu_parents.length > 1) {
|
||||
setTimeout(function () {
|
||||
$secondary_menu_toggler.addClass('oe_menu_opened');
|
||||
$clicked_menu.closest('ul').removeClass('o_hidden');
|
||||
}, 2000);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets all highlighted menu entries and
|
||||
* collapse all opened menu items.
|
||||
*/
|
||||
reset_menu: function () {
|
||||
var $main_menu = $('.f_launcher_content');
|
||||
var $main_menu_container = $main_menu.find('.collapse.show');
|
||||
var $active_entry = $main_menu.find('li.active');
|
||||
var $chevron_down = $main_menu.find('.fa-chevron-down');
|
||||
var $secondary_menu_link = $main_menu.find('.oe_menu_opened');
|
||||
var $secondary_menu_container = $main_menu.find('.oe_secondary_menu > .oe_secondary_submenu > li > .oe_secondary_submenu')
|
||||
|
||||
$main_menu_container.removeClass('show');
|
||||
$active_entry.removeClass('active');
|
||||
$chevron_down.removeClass('fa-chevron-down').addClass('fa-chevron-right');
|
||||
$secondary_menu_link.removeClass('oe_menu_opened');
|
||||
$secondary_menu_container.addClass('o_hidden');
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens a given menu by id, as if a user had browsed to that menu by hand
|
||||
* except does not trigger any event on the way
|
||||
*
|
||||
* @param {Number} id database id of the terminal menu to select
|
||||
*/
|
||||
open_menu: function (id) {
|
||||
var self = this;
|
||||
this.current_menu = id;
|
||||
session.active_id = id;
|
||||
var $clicked_menu, $sub_menu, $main_menu;
|
||||
$clicked_menu = this.$el.add(this.$secondary_menus).find('a[data-menu=' + id + ']');
|
||||
this.trigger('open_menu', id, $clicked_menu);
|
||||
|
||||
if (this.$secondary_menus.has($clicked_menu).length) {
|
||||
$sub_menu = $clicked_menu.parents('.oe_secondary_menu');
|
||||
$main_menu = this.$el.find('a[data-menu=' + $sub_menu.data('menu-parent') + ']');
|
||||
} else {
|
||||
$sub_menu = this.$secondary_menus.find('.oe_secondary_menu[data-menu-parent=' + $clicked_menu.attr('data-menu') + ']');
|
||||
$main_menu = $clicked_menu;
|
||||
}
|
||||
|
||||
// Activate current main menu
|
||||
this.$el.find('.active').removeClass('active');
|
||||
$main_menu.parent().addClass('active');
|
||||
|
||||
var isNotMainMenu = $clicked_menu.hasClass('oe_main_menu');
|
||||
if (this._isMainMenuClick || this.isLoadflag && isNotMainMenu) {
|
||||
var href_id = $sub_menu.attr('id');
|
||||
if (href_id && $sub_menu.attr('class').indexOf('in') === -1) {
|
||||
this.$secondary_menus.find("a[href='#" + href_id + "']").trigger('click');
|
||||
this.$secondary_menus.find("a[href='#" + href_id + " i']")
|
||||
.addClass('fa-chevron-right')
|
||||
.removeClass('fa-chevron-down');
|
||||
} else {
|
||||
$clicked_menu.parents('li.panel').find('.oe_main_menu_container .more-less a').trigger('click');
|
||||
this.$secondary_menus.find("a[href='#" + href_id + " i']")
|
||||
.addClass('fa-chevron-down')
|
||||
.removeClass('fa-chevron-right');
|
||||
}
|
||||
}
|
||||
|
||||
// Hide/Show the leftbar menu depending of the presence of sub-items
|
||||
this.$secondary_menus.toggleClass('o_hidden', !$sub_menu.children().length);
|
||||
|
||||
// Activate current menu item and show parents
|
||||
this.$secondary_menus.find('.active').removeClass('active');
|
||||
if ($main_menu !== $clicked_menu) {
|
||||
$clicked_menu.parents().removeClass('o_hidden');
|
||||
if ($clicked_menu.is('.oe_menu_toggler')) {
|
||||
$clicked_menu.toggleClass('oe_menu_opened').siblings('.oe_secondary_submenu:first').toggleClass('o_hidden');
|
||||
} else {
|
||||
$clicked_menu.parent().addClass('active');
|
||||
}
|
||||
this.$secondary_menus.find('.oe_main_menu_container').removeClass('active');
|
||||
$clicked_menu.parents('li.panel').find('.oe_main_menu_container').addClass('active');
|
||||
}
|
||||
$clicked_menu.closest('.panel').addClass('active')
|
||||
// add a tooltip to cropped menu items
|
||||
this.$secondary_menus.find('.oe_secondary_submenu li a span').each(function () {
|
||||
$(this).tooltip(this.scrollWidth > this.clientWidth ? {title: $(this).text().trim(), placement: 'right'} : 'dispose');
|
||||
});
|
||||
this.isLoadflag = false;
|
||||
},
|
||||
/**
|
||||
* Call open_menu on a menu_item that matches the action_id
|
||||
*
|
||||
* If `menuID` is a match on this action, open this menu_item.
|
||||
* Otherwise open the first menu_item that matches the action_id.
|
||||
*
|
||||
* @param {Number} id the action_id to match
|
||||
* @param {Number} [menuID] a menu ID that may match with provided action
|
||||
*/
|
||||
open_action: function (id, menuID) {
|
||||
var $menu = this.$el.add(this.$secondary_menus).find('a[data-action-id="' + id + '"]');
|
||||
if (!(menuID && $menu.filter("[data-menu='" + menuID + "']").length)) {
|
||||
// menuID doesn't match action, so pick first menu_item
|
||||
menuID = $menu.data('menu');
|
||||
}
|
||||
if (menuID) {
|
||||
this.open_menu(menuID);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Process a click on a menu item
|
||||
*
|
||||
* @param {Number} id the menu_id
|
||||
*/
|
||||
menu_click: function (id) {
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
|
||||
// find back the menuitem in dom to get the action
|
||||
var $item = this.$el.find('a[data-menu=' + id + ']');
|
||||
if (!$item.length) {
|
||||
$item = this.$secondary_menus.find('a[data-menu=' + id + ']');
|
||||
}
|
||||
var action_id = $item.data('action-id');
|
||||
// If first level menu doesnt have action trigger first leaf
|
||||
if (!action_id) {
|
||||
if (this.$el.has($item).length) {
|
||||
var $sub_menu = this.$secondary_menus.find('.oe_secondary_menu[data-menu-parent=' + id + ']');
|
||||
var $items = $sub_menu.find('a[data-action-id]').filter('[data-action-id!=""]');
|
||||
if ($items.length) {
|
||||
action_id = $items.data('action-id');
|
||||
id = $items.data('menu');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (action_id) {
|
||||
this.trigger_up('app_clicked', {
|
||||
action_id: action_id,
|
||||
menu_id: id,
|
||||
});
|
||||
} else {
|
||||
console.log('Menu no action found web test 04 will fail');
|
||||
}
|
||||
this._isActionId = action_id === undefined ? false : true;
|
||||
this.open_menu(id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Change the current top menu
|
||||
*
|
||||
* @param {int} [menu_id] the top menu id
|
||||
*/
|
||||
on_change_top_menu: function (menu_id) {
|
||||
var self = this;
|
||||
this.menu_click(menu_id);
|
||||
},
|
||||
on_menu_click: function (ev) {
|
||||
ev.preventDefault();
|
||||
if (!parseInt($(ev.currentTarget).data('menu'))) return;
|
||||
this._isMainMenuClick = $(ev.currentTarget).attr('class').indexOf('oe_main_menu') !== -1 ? true : false;
|
||||
this.menu_click($(ev.currentTarget).data('menu'));
|
||||
},
|
||||
});
|
||||
|
||||
return SideMenu;
|
||||
});
|
||||
|
||||
return SideMenu;
|
||||
});
|
||||
|
||||
flectra.define('web_flectra.sidemenu.AppsMenu', function(require) {
|
||||
flectra.define('web_flectra.sidemenu.AppsMenu', function (require) {
|
||||
"use strict";
|
||||
var AppsMenu = require('web.AppsMenu');
|
||||
var SideMenu = require('web_flectra.sidemenu');
|
||||
@@ -299,7 +347,7 @@ flectra.define('web_flectra.sidemenu.AppsMenu', function(require) {
|
||||
});
|
||||
});
|
||||
|
||||
flectra.define('web_flectra.sidemenu.webclient', function(require) {
|
||||
flectra.define('web_flectra.sidemenu.webclient', function (require) {
|
||||
"use strict";
|
||||
var Menu = require('web.Menu');
|
||||
var WebClient = require('web.WebClient');
|
||||
@@ -311,15 +359,15 @@ flectra.define('web_flectra.sidemenu.webclient', function(require) {
|
||||
var session = require('web.session');
|
||||
|
||||
WebClient.include({
|
||||
start : function () {
|
||||
start: function () {
|
||||
var self = this;
|
||||
this._super();
|
||||
return rpc.query({
|
||||
model: 'res.company', method: 'read',
|
||||
args: [[session.company_id], ['theme_menu_style']]
|
||||
}).then(function (res) {
|
||||
if(res[0].theme_menu_style == 'sidemenu') {
|
||||
$('.o-menu-toggle, .o_menu_sections').remove();
|
||||
model: 'res.company', method: 'read',
|
||||
args: [[session.company_id], ['theme_menu_style']]
|
||||
}).then(function (res) {
|
||||
if (res[0].theme_menu_style == 'sidemenu') {
|
||||
$('.o-menu-toggle, .o_menu_sections').remove();
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -339,9 +387,9 @@ flectra.define('web_flectra.sidemenu.webclient', function(require) {
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
bind_hashchange: function() {
|
||||
bind_hashchange: function () {
|
||||
var self = this;
|
||||
$(window).bind('hashchange', function(e) {
|
||||
$(window).bind('hashchange', function (e) {
|
||||
self.on_hashchange(e);
|
||||
});
|
||||
var didHashChanged = false;
|
||||
@@ -351,23 +399,23 @@ flectra.define('web_flectra.sidemenu.webclient', function(require) {
|
||||
|
||||
var state = $.bbq.getState(true);
|
||||
if (_.isEmpty(state) || state.action === "login") {
|
||||
self.sidemenu.is_bound.done(function() {
|
||||
self.sidemenu.is_bound.done(function () {
|
||||
self._rpc({
|
||||
model: 'res.users',
|
||||
method: 'read',
|
||||
args: [[session.uid], ['action_id']],
|
||||
})
|
||||
.done(function(result) {
|
||||
model: 'res.users',
|
||||
method: 'read',
|
||||
args: [[session.uid], ['action_id']],
|
||||
})
|
||||
.done(function (result) {
|
||||
if (didHashChanged) {
|
||||
return;
|
||||
}
|
||||
var data = result[0];
|
||||
if(data.action_id) {
|
||||
if (data.action_id) {
|
||||
self.action_manager.doAction(data.action_id[0]);
|
||||
self.sidemenu.open_action(data.action_id[0]);
|
||||
} else {
|
||||
var first_menu_id = self.sidemenu.$el.find("a:first").data("menu");
|
||||
if(first_menu_id) {
|
||||
if (first_menu_id) {
|
||||
self.sidemenu.menu_click(first_menu_id);
|
||||
}
|
||||
}
|
||||
@@ -378,7 +426,7 @@ flectra.define('web_flectra.sidemenu.webclient', function(require) {
|
||||
}
|
||||
},
|
||||
|
||||
on_hashchange: function(event) {
|
||||
on_hashchange: function (event) {
|
||||
this._super.apply(this, event);
|
||||
if (this._ignore_hashchange) {
|
||||
this._ignore_hashchange = false;
|
||||
@@ -389,8 +437,8 @@ flectra.define('web_flectra.sidemenu.webclient', function(require) {
|
||||
var stringstate = $.bbq.getState(false);
|
||||
var state = $.bbq.getState(true);
|
||||
if (!_.isEqual(self._current_state, stringstate)) {
|
||||
if(!state.action && state.menu_id) {
|
||||
self.sidemenu.is_bound.done(function() {
|
||||
if (!state.action && state.menu_id) {
|
||||
self.sidemenu.is_bound.done(function () {
|
||||
self.sidemenu.menu_click(state.menu_id);
|
||||
});
|
||||
} else if (state.menu_id) {
|
||||
@@ -409,21 +457,21 @@ flectra.define('web_flectra.sidemenu.webclient', function(require) {
|
||||
});
|
||||
},
|
||||
|
||||
on_menu_action: function(options) {
|
||||
on_menu_action: function (options) {
|
||||
var self = this;
|
||||
return this.menu_dp.add(data_manager.load_action(options.action_id))
|
||||
.then(function (result) {
|
||||
return self.action_mutex.exec(function() {
|
||||
return self.action_mutex.exec(function () {
|
||||
var completed = $.Deferred();
|
||||
$.when(self.action_manager.do_action(result, {
|
||||
clear_breadcrumbs: true,
|
||||
action_menu_id: options.id,
|
||||
})).fail(function() {
|
||||
})).fail(function () {
|
||||
self.sidemenu.open_menu(options.previous_menu_id);
|
||||
}).always(function() {
|
||||
}).always(function () {
|
||||
completed.resolve();
|
||||
});
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
completed.resolve();
|
||||
}, 2000);
|
||||
// We block the menu when clicking on an element until the action has correctly finished
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/* Error: Undefined variable.
|
||||
* ,
|
||||
* 4 | $theme_sidebar_submenu_color: lighten($theme-sidebar-color, 13.5%);
|
||||
* | ^^^^^^^^^^^^^^^^^^^^
|
||||
* '
|
||||
* sidebar.scss 4:39 root stylesheet */
|
||||
|
||||
body::before {
|
||||
font-family: "Source Code Pro", "SF Mono", Monaco, Inconsolata, "Fira Mono",
|
||||
"Droid Sans Mono", monospace, monospace;
|
||||
white-space: pre;
|
||||
display: block;
|
||||
padding: 1em;
|
||||
margin-bottom: 1em;
|
||||
border-bottom: 2px solid black;
|
||||
content: "Error: Undefined variable.\a \2577 \a 4 \2502 $theme_sidebar_submenu_color: lighten($theme-sidebar-color, 13.5%);\a \2502 ^^^^^^^^^^^^^^^^^^^^\a \2575 \a sidebar.scss 4:39 root stylesheet";
|
||||
}
|
||||
@@ -8,8 +8,8 @@ $Gray99: #dadada;
|
||||
$font_name: "sans-serif";
|
||||
$font_size: 0.85em;
|
||||
$menu_height: $o-navbar-height;
|
||||
$sidebar_collapsed_width: 56px;
|
||||
$sidebar_width: 240px;
|
||||
$sidebar_collapsed_width: 68px;
|
||||
$sidebar_width: 252px;
|
||||
$theme_color: #ffffff;
|
||||
$highlight_color: #009efb;
|
||||
$hover_color: #ddd;
|
||||
@@ -29,20 +29,28 @@ body[data-menu="sidemenu"].o_web_client {
|
||||
z-index: 199;
|
||||
max-height: calc(100vH - #{$menu_height});
|
||||
height: calc(100vH - #{$menu_height});
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
font-family: $font_name;
|
||||
&::-webkit-scrollbar{
|
||||
background-color: $theme-sidebar-color;
|
||||
width: 8px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb{
|
||||
border-radius: 10px;
|
||||
background-color: darken($o-brand-primary, 10%);
|
||||
}
|
||||
.f_launcher_content {
|
||||
transition: all 0.4s;
|
||||
transition: all 0.3s;
|
||||
&:hover{
|
||||
transform: translate3d(0, 0, 0);
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
}
|
||||
position: relative;
|
||||
background-color: $theme-sidebar-color;
|
||||
height: 100%;
|
||||
max-width: $sidebar_width;
|
||||
width: $sidebar_width;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overflow: hidden;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
@@ -286,10 +294,15 @@ body[data-menu="sidemenu"].o_web_client {
|
||||
/// ACTION MANAGER LAYOUT
|
||||
/////////////////////////////
|
||||
>.o_action_manager {
|
||||
@media (max-width: 768px) {
|
||||
@media (max-width: 1024px) {
|
||||
flex: 1 1;
|
||||
padding-left: $sidebar_collapsed_width;
|
||||
}
|
||||
&.force_mobile {
|
||||
flex: 1 1;
|
||||
padding-left: $sidebar_collapsed_width;
|
||||
}
|
||||
height: calc(100% - #{$menu_height}) !important;
|
||||
padding-left: $sidebar_collapsed_width;
|
||||
padding-left: $sidebar_width;
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,21 @@
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). -->
|
||||
<template>
|
||||
<t t-extend="Menu">
|
||||
<t t-jquery=".o_menu_apps" t-operation="append">
|
||||
<li>
|
||||
<a href="#" class="o-menu-slide full">
|
||||
<i class="fa fa-compress"/>
|
||||
</a>
|
||||
</li>
|
||||
</t>
|
||||
<t t-jquery=".o_menu_apps" t-operation="after">
|
||||
<!-- Hamburger button to show submenus in sm screens -->
|
||||
<button
|
||||
class="o-menu-toggle d-md-none"
|
||||
data-toggle="collapse"
|
||||
data-target=".o_main_navbar .o_menu_sections"
|
||||
class="o-menu-toggle d-md-none"
|
||||
data-toggle="collapse"
|
||||
data-target=".o_main_navbar .o_menu_sections"
|
||||
>
|
||||
<i class="fa fa-bars" />
|
||||
<i class="fa fa-bars"/>
|
||||
</button>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
Reference in new issue
Block a user