[IMP] Web: navbar isn't displayed on several lines while rendering

- Add a new SystrayMenu widget to improve and facilitate the way
    of adding widgets in .oe_systray
  - Rendering of the modules menu now waits for the systray and
    user menus to be rendered
  - A few refactoring of the UserMenu and Menu widgets
This commit is contained in:
Aaron Bohy
2015-01-07 15:13:51 +01:00
parent ecc3bb7647
commit ba083dbb47
7 changed files with 86 additions and 75 deletions
@@ -69,25 +69,11 @@ openerp.hr_attendance = function (instance) {
},
});
instance.web.UserMenu.include({
do_update: function () {
this._super();
var self = this;
this.update_promise.done(function () {
if (!_.isUndefined(self.attendanceslider)) {
return;
}
// check current user is an employee
var Users = new instance.web.Model('res.users');
Users.call('has_group', ['base.group_user']).done(function(is_employee) {
if (is_employee) {
self.attendanceslider = new instance.hr_attendance.AttendanceSlider(self);
self.attendanceslider.prependTo(instance.webclient.$('.oe_systray'));
} else {
self.attendanceslider = null;
}
});
});
},
});
// Put the AttendanceSlider widget in the systray menu if the user is an employee
var Users = new instance.web.Model('res.users');
Users.call('has_group', ['base.group_user']).done(function(is_employee) {
if (is_employee) {
instance.web.SystrayItems.push(instance.hr_attendance.AttendanceSlider);
}
})
};
+17 -19
View File
@@ -601,31 +601,29 @@
events: {
"click": "clicked",
},
start: function() {
// Create the InstantMessaging widget and put it in the DOM
var im = new openerp.im_chat.InstantMessaging(self);
openerp.im_chat.single = im;
im.appendTo(openerp.client.$el);
// Bind the click action to the ImTopButton
this.on("clicked", im, im.switch_display);
return this._super();
},
clicked: function(ev) {
ev.preventDefault();
this.trigger("clicked");
},
});
if(openerp.web && openerp.web.UserMenu) {
openerp.web.UserMenu.include({
do_update: function(){
var self = this;
var Users = new openerp.web.Model('res.users');
Users.call('has_group', ['base.group_user']).done(function(is_employee) {
if (is_employee) {
self.update_promise.then(function() {
var im = new openerp.im_chat.InstantMessaging(self);
openerp.im_chat.single = im;
im.appendTo(openerp.client.$el);
var button = new openerp.im_chat.ImTopButton(this);
button.on("clicked", im, im.switch_display);
button.appendTo(window.$('.oe_systray'));
});
}
});
return this._super.apply(this, arguments);
},
// Guard: only for the backend
if (openerp.web && openerp.web.Model) {
// Put the ImTopButton widget in the systray menu if the user is an employee
var Users = new openerp.web.Model('res.users');
Users.call('has_group', ['base.group_user']).done(function(is_employee) {
if (is_employee) {
openerp.web.SystrayItems.push(openerp.im_chat.ImTopButton);
}
});
}
+2 -10
View File
@@ -2077,14 +2077,6 @@ openerp.mail = function (session) {
},
});
session.web.UserMenu.include({
do_update: function(){
var self = this;
this._super.apply(this, arguments);
this.update_promise.then(function() {
var mail_button = new session.web.ComposeMessageTopButton();
mail_button.appendTo(session.webclient.$el.find('.oe_systray'));
});
},
});
// Put the ComposeMessageTopButton widget in the systray menu
session.web.SystrayItems.push(session.web.ComposeMessageTopButton);
};
+1 -1
View File
@@ -30,7 +30,7 @@
}
#oe_main_menu_navbar .oe_topbar_avatar {
max-height: 18px;
width: auto;
width: 18px;
}
#oe_main_menu_navbar.navbar {
+1 -1
View File
@@ -153,7 +153,7 @@ $sheet-padding: 16px
font-size: 13px
.oe_topbar_avatar
max-height: 18px
width: auto
width: 18px
#oe_main_menu_navbar.navbar
margin-bottom: 0px
+57 -22
View File
@@ -756,12 +756,39 @@ instance.web.ChangePassword = instance.web.Widget.extend({
});
instance.web.client_actions.add("change_password", "instance.web.ChangePassword");
instance.web.SystrayItems = [];
instance.web.SystrayMenu = instance.web.Widget.extend({
/**
* This widget renders the systray menu. It creates and renders widgets
* pushed in instance.web.SystrayItems.
*/
init: function(parent) {
this._super(parent);
this.items = [];
this.load = $.Deferred();
},
start: function() {
var self = this;
self._super.apply(this, arguments);
self.load_items();
return $.when.apply($, self.items).done(function () {
self.load.resolve();
});
},
load_items: function() {
var self = this;
_.each(instance.web.SystrayItems, function(widgetCls) {
var cur_systray_item = new widgetCls(self);
self.items.push(cur_systray_item.appendTo(self.$el));
});
},
});
instance.web.Menu = instance.web.Widget.extend({
init: function() {
var self = this;
this._super.apply(this, arguments);
this.is_bound = $.Deferred();
this.maximum_visible_links = 'auto'; // # of menu to show. 0 = do not crop, 'auto' = algo
this.data = {data:{children:[]}};
this.on("menu_bound", this, function() {
// launch the fetch of needaction counters, asynchronous
@@ -791,10 +818,9 @@ instance.web.Menu = instance.web.Widget.extend({
self.open_menu(self.current_menu);
}
this.trigger('menu_bound');
var lazyreflow = _.debounce(this.reflow.bind(this), 200);
instance.web.bus.on('resize', this, function() {
if (parseInt(self.$el.parent().css('width')) <= 768 ) {
if ($(window).width() < 768 ) {
lazyreflow('all_outside');
} else {
lazyreflow();
@@ -829,9 +855,8 @@ instance.web.Menu = instance.web.Widget.extend({
* Reflow the menu items and dock overflowing items into a "More" menu item.
* Automatically called when 'menu_bound' event is triggered and on window resizing.
*
* @param {string} behavior If set to 'all_outside', all the items are displayed. If set to
* 'all_inside', all the items are hidden under the more item. If not set, only the
* overflowing items are hidden.
* @param {string} behavior If set to 'all_outside', all the items are displayed.
* If not set, only the overflowing items are hidden.
*/
reflow: function(behavior) {
var self = this;
@@ -843,32 +868,33 @@ instance.web.Menu = instance.web.Widget.extend({
// 'all_outside' beahavior should display all the items, so hide the more menu and exit
if (behavior === 'all_outside') {
// Show list of menu items
self.$el.show();
this.$el.find('li').show();
$more_container.hide();
return;
}
// Hide all menu items
var $toplevel_items = this.$el.find('li').not($more_container).not($systray.find('li')).hide();
// Show list of menu items (which is empty for now since all menu items are hidden)
self.$el.show();
$toplevel_items.each(function() {
// In all inside mode, we do not compute to know if we must hide the items, we hide them all
if (behavior === 'all_inside') {
return false;
}
var remaining_space = self.$el.parent().width() - $more_container.outerWidth();
self.$el.parent().children(':visible').each(function() {
remaining_space -= $(this).outerWidth();
});
if ($(this).width() > remaining_space) {
return false;
if ($(this).width() >= remaining_space) {
return false; // the current item will be appended in more_container
}
$(this).show();
$(this).show(); // show the current item in menu bar
});
$more.append($toplevel_items.filter(':hidden').show());
$more_container.toggle(!!$more.children().length || behavior === 'all_inside');
$more_container.toggle(!!$more.children().length);
// Hide toplevel item if there is only one
var $toplevel = this.$el.children("li:visible");
if ($toplevel.length === 1 && behavior != 'all_inside') {
var $toplevel = self.$el.children("li:visible");
if ($toplevel.length === 1) {
$toplevel.hide();
}
},
@@ -1014,7 +1040,6 @@ instance.web.UserMenu = instance.web.Widget.extend({
},
start: function() {
var self = this;
this._super.apply(this, arguments);
this.$el.on('click', '.dropdown-menu li a[data-menu]', function(ev) {
ev.preventDefault();
var f = self['on_menu_' + $(this).data('menu')];
@@ -1023,6 +1048,7 @@ instance.web.UserMenu = instance.web.Widget.extend({
}
});
this.$el.parent().show()
return this._super.apply(this, arguments);
},
do_update: function () {
var self = this;
@@ -1286,15 +1312,24 @@ instance.web.WebClient = instance.web.Client.extend({
this.$('.oe_logo img').click(function(ev) {
self.on_logo_click(ev);
});
// Create the user menu (rendered client-side)
self.user_menu = new instance.web.UserMenu(self);
var user_menu_loaded = self.user_menu.appendTo(this.$el.parents().find('.oe_user_menu_placeholder'));
self.user_menu.on('user_logout', self, self.on_logout);
self.user_menu.do_update();
// Create the systray menu (rendered server-side)
self.systray_menu = new instance.web.SystrayMenu(self);
self.systray_menu.setElement(this.$el.parents().find('.oe_systray'));
var systray_menu_loaded = self.systray_menu.start();
// Create and render the menu once both systray and user menus are rendered
// to prevent overflows while loading
// Menu is rendered server-side thus we don't want the widget to create any dom
self.menu = new instance.web.Menu(self);
self.menu.setElement(this.$el.parents().find('.oe_application_menu_placeholder'));
self.menu.start();
self.menu.on('menu_click', this, this.on_menu_action);
self.user_menu = new instance.web.UserMenu(self);
self.user_menu.appendTo(this.$el.parents().find('.oe_user_menu_placeholder'));
self.user_menu.on('user_logout', self, self.on_logout);
self.user_menu.do_update();
$.when(systray_menu_loaded, user_menu_loaded).done(function() {
self.menu.start();
});
self.bind_hashchange();
self.set_title();
self.check_timezone();
+1 -1
View File
@@ -142,7 +142,7 @@
</template>
<template id="web.menu">
<ul class="nav navbar-nav navbar-left oe_application_menu_placeholder">
<ul class="nav navbar-nav navbar-left oe_application_menu_placeholder" style="display: none;">
<li t-foreach="menu_data['children']" t-as="menu">
<t t-call="web.menu_link"/>
</li>