X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=addons%2Fweb%2Fstatic%2Fsrc%2Fjs%2Fchrome.js;h=de49b11645d7dade982861316ca65b629283faa0;hb=97110c0a48c661a222fa9c91c0037c8e2caa8864;hp=ee8ca5d34d5f45460bee024e61fc858ef907a751;hpb=7461f884738487bc7bc0d8c0c3e1e0cc9c317fba;p=odoo%2Fodoo.git diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index ee8ca5d..de49b11 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -42,6 +42,16 @@ instance.web.Notification = instance.web.Widget.extend({ } }); +instance.web.action_notify = function(element, action) { + element.do_notify(action.params.title, action.params.text, action.params.sticky); +}; +instance.web.client_actions.add("action_notify", "instance.web.action_notify"); + +instance.web.action_warn = function(element, action) { + element.do_warn(action.params.title, action.params.text, action.params.sticky); +}; +instance.web.client_actions.add("action_warn", "instance.web.action_warn"); + /** * The very minimal function everything should call to create a dialog * in OpenERP Web Client. @@ -237,6 +247,13 @@ instance.web.CrashManager = instance.web.Class.extend({ if (!this.active) { return; } + // yes, exception handling is shitty + if (error.code === 300 && error.data && error.data.type == "client_exception" && error.data.debug.match("SessionExpiredException")) { + this.show_warning({type: "Session Expired", data: { + fault_code: _t("Your OpenERP session expired. Please refresh the current web page.") + }}); + return; + } if (error.data.fault_code) { var split = ("" + error.data.fault_code).split('\n')[0].split(' -- '); if (split.length > 1) { @@ -289,7 +306,7 @@ instance.web.CrashManager = instance.web.Class.extend({ }); instance.web.Loading = instance.web.Widget.extend({ - template: 'Loading', + template: _t("Loading"), init: function(parent) { this._super(parent); this.count = 0; @@ -363,7 +380,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ var fetch_langs = this.rpc("/web/session/get_lang_list", {}).done(function(result) { self.lang_list = result; }); - return $.when(fetch_db, fetch_langs).done(self.do_render); + return $.when(fetch_db, fetch_langs).always(self.do_render); }, do_render: function() { var self = this; @@ -390,11 +407,11 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ self.$el.find("form[name=restore_db_form]").validate({ submitHandler: self.do_restore }); self.$el.find("form[name=change_pwd_form]").validate({ messages: { - old_pwd: "Please enter your previous password", - new_pwd: "Please enter your new password", + old_pwd: _t("Please enter your previous password"), + new_pwd: _t("Please enter your new password"), confirm_pwd: { - required: "Please confirm your new password", - equalTo: "The confirmation does not match the password" + required: _t("Please confirm your new password"), + equalTo: _t("The confirmation does not match the password") } }, submitHandler: self.do_change_password @@ -463,9 +480,14 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ 'login': 'admin', 'password': form_obj['create_admin_pwd'], 'login_successful': function() { - self.do_action("reload"); + var url = '/?db=' + form_obj['db_name']; + if (self.session.debug) { + url += '&debug'; + } + instance.web.redirect(url); }, }, + _push_me: false, }; self.do_action(client_action); }); @@ -478,7 +500,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ self.display_error(result); return; } - self.do_notify("Duplicating database", "The database has been duplicated."); + self.do_notify(_t("Duplicating database"), _t("The database has been duplicated.")); self.start(); }); }, @@ -488,7 +510,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ fields = $form.serializeArray(), $db_list = $form.find('[name=drop_db]'), db = $db_list.val(); - if (!db || !confirm("Do you really want to delete the database: " + db + " ?")) { + if (!db || !confirm(_.str.sprintf(_t("Do you really want to delete the database: %s ?"), db))) { return; } self.rpc("/web/database/drop", {'fields': fields}).done(function(result) { @@ -496,7 +518,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ self.display_error(result); return; } - self.do_notify("Dropping database", "The database '" + db + "' has been dropped"); + self.do_notify(_t("Dropping database"), _.str.sprintf(_t("The database %s has been dropped"), db)); self.start(); }); }, @@ -511,7 +533,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ error: function(error){ if(error){ self.display_error({ - title: 'Backup Database', + title: _t("Backup Database"), error: 'AccessDenied' }); } @@ -534,13 +556,13 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ if (body.indexOf('403 Forbidden') !== -1) { self.display_error({ - title: 'Access Denied', - error: 'Incorrect super-administrator password' + title: _t("Access Denied"), + error: _t("Incorrect super-administrator password") }); } else { self.display_error({ - title: 'Restore Database', - error: 'Could not restore the database' + title: _t("Restore Database"), + error: _t("Could not restore the database") }); } }, @@ -560,13 +582,12 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ return; } self.unblockUI(); - self.do_notify("Changed Password", "Password has been changed successfully"); + self.do_notify(_t("Changed Password"), _t("Password has been changed successfully")); }); }, do_exit: function () { this.$el.remove(); - instance.webclient.toggle_bars(false); - this.do_action('login'); + instance.webclient.show_login(); } }); instance.web.client_actions.add("database_manager", "instance.web.DatabaseManager"); @@ -574,6 +595,11 @@ instance.web.client_actions.add("database_manager", "instance.web.DatabaseManage instance.web.Login = instance.web.Widget.extend({ template: "Login", remember_credentials: true, + events: { + 'change input[name=db],select[name=db]': function(ev) { + this.set('database_selector', $(ev.currentTarget).val()); + }, + }, init: function(parent, action) { this._super(parent); @@ -585,18 +611,18 @@ instance.web.Login = instance.web.Widget.extend({ if (_.isEmpty(this.params)) { this.params = $.bbq.getState(true); } + if (action && action.params && action.params.db) { + this.params.db = action.params.db; + } else if ($.deparam.querystring().db) { + this.params.db = $.deparam.querystring().db; + } + if (this.params.db) { + this.selected_db = this.params.db; + } if (this.params.login_successful) { this.on('login_successful', this, this.params.login_successful); } - - if (this.has_local_storage && this.remember_credentials) { - this.selected_db = localStorage.getItem('last_db_login_success'); - this.selected_login = localStorage.getItem('last_login_login_success'); - if (jQuery.deparam(jQuery.param.querystring()).debug !== undefined) { - this.selected_password = localStorage.getItem('last_password_login_success'); - } - } }, start: function() { var self = this; @@ -604,24 +630,55 @@ instance.web.Login = instance.web.Widget.extend({ self.$el.find('.oe_login_manage_db').click(function() { self.do_action("database_manager"); }); + self.on('change:database_selector', this, function() { + this.database_selected(this.get('database_selector')); + }); var d = $.when(); - if ($.deparam.querystring().db) { - self.params.db = $.deparam.querystring().db; + if ($.param.fragment().token) { + self.params.token = $.param.fragment().token; } // used by dbmanager.do_create via internal client action if (self.params.db && self.params.login && self.params.password) { d = self.do_login(self.params.db, self.params.login, self.params.password); } else { - if (self.params.db) { - self.on_db_loaded([self.params.db]) - } else { - d = self.rpc("/web/database/get_list", {}).done(self.on_db_loaded).fail(self.on_db_failed); - } + d = self.rpc("/web/database/get_list", {}) + .done(self.on_db_loaded) + .fail(self.on_db_failed) + .always(function() { + if (self.selected_db && self.has_local_storage && self.remember_credentials) { + self.$("[name=login]").val(localStorage.getItem(self.selected_db + '|last_login') || ''); + if (self.session.debug) { + self.$("[name=password]").val(localStorage.getItem(self.selected_db + '|last_password') || ''); + } + } + }); } return d; }, + remember_last_used_database: function(db) { + // This cookie will be used server side in order to avoid db reloading on first visit + var ttl = 24 * 60 * 60 * 365; + document.cookie = [ + 'last_used_database=' + db, + 'path=/', + 'max-age=' + ttl, + 'expires=' + new Date(new Date().getTime() + ttl * 1000).toGMTString() + ].join(';'); + }, + database_selected: function(db) { + var params = $.deparam.querystring(); + params.db = db; + this.remember_last_used_database(db); + this.$('.oe_login_dbpane').empty().text(_t('Loading...')); + this.$('[name=login], [name=password]').prop('readonly', true); + instance.web.redirect('/?' + $.param(params)); + }, on_db_loaded: function (result) { + var self = this; this.db_list = result; + if (!this.selected_db) { + this.selected_db = result[0]; + } this.$("[name=db]").replaceWith(QWeb.render('Login.dblist', { db_list: this.db_list, selected_db: this.selected_db})); if(this.db_list.length === 0) { this.do_action("database_manager"); @@ -642,7 +699,7 @@ instance.web.Login = instance.web.Widget.extend({ } var db = this.$("form [name=db]").val(); if (!db) { - this.do_warn("Login", "No database selected !"); + this.do_warn(_t("Login"), _t("No database selected !")); return false; } var login = this.$("form input[name=login]").val(); @@ -662,23 +719,17 @@ instance.web.Login = instance.web.Widget.extend({ self.hide_error(); self.$(".oe_login_pane").fadeOut("slow"); return this.session.session_authenticate(db, login, password).then(function() { - if (self.has_local_storage) { - if(self.remember_credentials) { - localStorage.setItem('last_db_login_success', db); - localStorage.setItem('last_login_login_success', login); - if (jQuery.deparam(jQuery.param.querystring()).debug !== undefined) { - localStorage.setItem('last_password_login_success', password); - } - } else { - localStorage.setItem('last_db_login_success', ''); - localStorage.setItem('last_login_login_success', ''); - localStorage.setItem('last_password_login_success', ''); + self.remember_last_used_database(db); + if (self.has_local_storage && self.remember_credentials) { + localStorage.setItem(db + '|last_login', login); + if (self.session.debug) { + localStorage.setItem(db + '|last_password', password); } } self.trigger('login_successful'); }, function () { self.$(".oe_login_pane").fadeIn("fast", function() { - self.show_error("Invalid username or password"); + self.show_error(_t("Invalid username or password")); }); }); }, @@ -692,6 +743,7 @@ instance.web.Login = instance.web.Widget.extend({ }); instance.web.client_actions.add("login", "instance.web.Login"); + /** * Redirect to url by replacing window.location * If wait is true, sleep 1s and wait for the server i.e. after a restart. @@ -729,6 +781,9 @@ instance.web.Reload = function(parent, action) { var sobj = $.deparam(l.search.substr(1)); sobj.ts = new Date().getTime(); + if (params.url_search) { + sobj = _.extend(sobj, params.url_search); + } var search = '?' + $.param(sobj); var hash = l.hash; @@ -765,7 +820,7 @@ instance.web.ChangePassword = instance.web.Widget.extend({ template: "ChangePassword", start: function() { var self = this; - this.getParent().dialog_title = "Change Password"; + this.getParent().dialog_title = _t("Change Password"); var $button = self.$el.find('.oe_form_button'); $button.appendTo(this.getParent().$buttons); $button.eq(2).click(function(){ @@ -799,10 +854,23 @@ instance.web.client_actions.add("change_password", "instance.web.ChangePassword" instance.web.Menu = instance.web.Widget.extend({ template: 'Menu', init: function() { + var self = this; this._super.apply(this, arguments); this.has_been_loaded = $.Deferred(); this.maximum_visible_links = 'auto'; // # of menu to show. 0 = do not crop, 'auto' = algo this.data = {data:{children:[]}}; + this.on("menu_loaded", this, function (menu_data) { + self.reflow(); + // launch the fetch of needaction counters, asynchronous + if (!_.isEmpty(menu_data.all_menu_ids)) { + this.do_load_needaction(menu_data.all_menu_ids); + } + }); + var lazyreflow = _.debounce(this.reflow.bind(this), 200); + instance.web.bus.on('resize', this, function() { + self.$el.height(0); + lazyreflow(); + }); }, start: function() { this._super.apply(this, arguments); @@ -818,16 +886,10 @@ instance.web.Menu = instance.web.Widget.extend({ }, menu_loaded: function(data) { var self = this; - this.data = data; + this.data = {data: data}; this.renderElement(); - this.limit_entries(); - // Hide toplevel item if there is only one - var $toplevel = this.$("li") - if($toplevel.length == 1) { - $toplevel.hide(); - } this.$secondary_menus.html(QWeb.render("Menu.secondary", { widget : this })); - this.$el.on('click', 'a[data-menu]', this.on_menu_click); + this.$el.on('click', 'a[data-menu]', this.on_top_menu_click); // Hide second level submenus this.$secondary_menus.find('.oe_menu_toggler').siblings('.oe_secondary_submenu').hide(); if (self.current_menu) { @@ -835,40 +897,57 @@ instance.web.Menu = instance.web.Widget.extend({ } this.trigger('menu_loaded', data); this.has_been_loaded.resolve(); - // Now launch the fetch of needaction counters, asynchronous - this.rpc("web/menu/load_needaction", {menu_ids: false}).done(function(r) { + }, + do_load_needaction: function (menu_ids) { + var self = this; + menu_ids = _.compact(menu_ids); + if (_.isEmpty(menu_ids)) { + return $.when(); + } + return this.rpc("/web/menu/load_needaction", {'menu_ids': menu_ids}).done(function(r) { self.on_needaction_loaded(r); }); }, on_needaction_loaded: function(data) { var self = this; this.needaction_data = data; - _.each(this.needaction_data.data, function (item, menu_id) { + _.each(this.needaction_data, function (item, menu_id) { var $item = self.$secondary_menus.find('a[data-menu="' + menu_id + '"]'); - $item.remove('oe_menu_counter'); + $item.find('.oe_menu_counter').remove(); if (item.needaction_counter && item.needaction_counter > 0) { - $item.append('
' + item.needaction_counter + '
'); + $item.append(QWeb.render("Menu.needaction_counter", { widget : item })); } }); }, - limit_entries: function() { - var maximum_visible_links = this.maximum_visible_links; - if (maximum_visible_links === 'auto') { - maximum_visible_links = this.auto_limit_entries(); - } - if (maximum_visible_links < this.data.data.children.length) { - var $more = $(QWeb.render('Menu.more')), - $index = this.$el.find('li').eq(maximum_visible_links - 1); - $index.after($more); - //$('.oe_topbar').append($more); - $more.find('.oe_menu_more').append($index.next().nextAll()); + /** + * Reflow the menu items and dock overflowing items into a "More" menu item. + * Automatically called when 'menu_loaded' event is triggered and on window resizing. + */ + reflow: function() { + var self = this; + this.$el.height('auto').show(); + var $more_container = this.$('.oe_menu_more_container').hide(); + var $more = this.$('.oe_menu_more'); + $more.children('li').insertBefore($more_container); + var $toplevel_items = this.$el.children('li').not($more_container).hide(); + $toplevel_items.each(function() { + 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; + } + $(this).show(); + }); + $more.append($toplevel_items.filter(':hidden').show()); + $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) { + $toplevel.hide(); } }, - auto_limit_entries: function() { - // TODO: auto detect overflow and bind window on resize - var width = $(window).width(); - return Math.floor(width / 125); - }, /** * 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 @@ -960,11 +1039,38 @@ instance.web.Menu = instance.web.Widget.extend({ } this.open_menu(id); }, + do_reload_needaction: function () { + var self = this; + if (self.current_menu) { + self.do_load_needaction([self.current_menu]).then(function () { + self.trigger("need_action_reloaded"); + }); + } + }, /** * Jquery event handler for menu click * * @param {Event} ev the jquery event */ + on_top_menu_click: function(ev) { + var self = this; + var id = $(ev.currentTarget).data('menu'); + var menu_ids = [id]; + var menu = _.filter(this.data.data.children, function (menu) {return menu.id == id;})[0]; + function add_menu_ids (menu) { + if (menu.children) { + _.each(menu.children, function (menu) { + menu_ids.push(menu.id); + add_menu_ids(menu); + }); + } + }; + add_menu_ids(menu); + self.do_load_needaction(menu_ids).then(function () { + self.trigger("need_action_reloaded"); + }); + this.on_menu_click(ev); + }, on_menu_click: function(ev) { ev.preventDefault(); var needaction = $(ev.target).is('div.oe_menu_counter'); @@ -997,20 +1103,15 @@ instance.web.UserMenu = instance.web.Widget.extend({ if (!self.session.uid) return; var func = new instance.web.Model("res.users").get_func("read"); - return func(self.session.uid, ["name", "company_id"]).then(function(res) { + return self.alive(func(self.session.uid, ["name", "company_id"])).then(function(res) { var topbar_name = res.name; if(instance.session.debug) topbar_name = _.str.sprintf("%s (%s)", topbar_name, instance.session.db); if(res.company_id[0] > 1) topbar_name = _.str.sprintf("%s (%s)", topbar_name, res.company_id[1]); self.$el.find('.oe_topbar_name').text(topbar_name); - if(!instance.session.debug) { - self.rpc("/web/database/get_list", {}).done( function(result) { - if (result.length > 1) { - topbar_name = _.str.sprintf("%s (%s)", topbar_name, instance.session.db); - } - self.$el.find('.oe_topbar_name').text(topbar_name); - }); + if (!instance.session.debug) { + topbar_name = _.str.sprintf("%s (%s)", topbar_name, instance.session.db); } var avatar_src = self.session.url('/web/binary/image', {model:'res.users', field: 'image_small', id: self.session.uid}); $avatar.attr('src', avatar_src); @@ -1018,6 +1119,9 @@ instance.web.UserMenu = instance.web.Widget.extend({ }; this.update_promise = this.update_promise.then(fct, fct); }, + on_menu_help: function() { + window.open('http://help.openerp.com', '_blank'); + }, on_menu_logout: function() { this.trigger('user_logout'); }, @@ -1114,16 +1218,21 @@ instance.web.Client = instance.web.Widget.extend({ instance.web.WebClient = instance.web.Client.extend({ _template: 'WebClient', + events: { + 'click .oe_logo_edit_admin': 'logo_edit' + }, init: function(parent) { this._super(parent); this._current_state = null; + this.menu_dm = new instance.web.DropMisordered(); + this.action_mutex = new $.Mutex(); }, start: function() { var self = this; return $.when(this._super()).then(function() { - self.$(".oe_logo").attr("href", $.param.fragment("" + window.location, "", 2).slice(0, -1)); if (jQuery.param !== undefined && jQuery.deparam(jQuery.param.querystring()).kitten !== undefined) { $("body").addClass("kitten-mode-activated"); + $("body").css("background-image", "url(" + instance.session.origin + "/web/static/src/img/back-enable.jpg" + ")"); if ($.blockUI) { $.blockUI.defaults.message = ''; } @@ -1169,6 +1278,7 @@ instance.web.WebClient = instance.web.Client.extend({ show_application: function() { var self = this; self.toggle_bars(true); + self.update_logo(); self.menu = new instance.web.Menu(self); self.menu.replace(this.$el.find('.oe_menu_placeholder')); self.menu.on('menu_click', this, this.on_menu_action); @@ -1180,28 +1290,60 @@ instance.web.WebClient = instance.web.Client.extend({ self.set_title(); self.check_timezone(); }, - check_timezone: function() { + update_logo: function() { + var img = this.session.url('/web/binary/company_logo'); + this.$('.oe_logo img').attr('src', '').attr('src', img); + this.$('.oe_logo_edit').toggleClass('oe_logo_edit_admin', this.session.uid === 1); + }, + logo_edit: function(ev) { var self = this; - var user_offset = instance.session.user_context.tz_offset; - var offset = -(new Date().getTimezoneOffset()); - // _.str.sprintf()'s zero front padding is buggy with signed decimals, so doing it manually - var browser_offset = (offset < 0) ? "-" : "+"; - browser_offset += _.str.sprintf("%02d", Math.abs(offset / 60)); - browser_offset += _.str.sprintf("%02d", Math.abs(offset % 60)); - if (browser_offset !== user_offset) { - var notification = this.do_warn(_t("Timezone"), QWeb.render('WebClient.timezone_notification', { - user_timezone: instance.session.user_context.tz || 'UTC', - user_offset: user_offset, - browser_offset: browser_offset, - }), true); - notification.element.find('.oe_webclient_timezone_notification').on('click', function() { - notification.close(); - }).find('a').on('click', function() { - notification.close(); - self.user_menu.on_menu_settings(); - return false; + self.alive(new instance.web.Model("res.users").get_func("read")(this.session.uid, ["company_id"])).then(function(res) { + self.rpc("/web/action/load", { action_id: "base.action_res_company_form" }).done(function(result) { + result.res_id = res['company_id'][0]; + result.target = "new"; + result.views = [[false, 'form']]; + result.flags = { + action_buttons: true, + }; + self.action_manager.do_action(result); + var form = self.action_manager.dialog_widget.views.form.controller; + form.on("on_button_cancel", self.action_manager.dialog, self.action_manager.dialog.close); + form.on('record_saved', self, function() { + self.action_manager.dialog.close(); + self.update_logo(); + }); }); - } + }); + return false; + }, + check_timezone: function() { + var self = this; + return self.alive(new instance.web.Model('res.users').call('read', [[this.session.uid], ['tz_offset']])).then(function(result) { + var user_offset = result[0]['tz_offset']; + var offset = -(new Date().getTimezoneOffset()); + // _.str.sprintf()'s zero front padding is buggy with signed decimals, so doing it manually + var browser_offset = (offset < 0) ? "-" : "+"; + browser_offset += _.str.sprintf("%02d", Math.abs(offset / 60)); + browser_offset += _.str.sprintf("%02d", Math.abs(offset % 60)); + if (browser_offset !== user_offset) { + var $icon = $(QWeb.render('WebClient.timezone_systray')); + $icon.on('click', function() { + var notification = self.do_warn(_t("Timezone mismatch"), QWeb.render('WebClient.timezone_notification', { + user_timezone: instance.session.user_context.tz || 'UTC', + user_offset: user_offset, + browser_offset: browser_offset, + }), true); + notification.element.find('.oe_webclient_timezone_notification').on('click', function() { + notification.close(); + }).find('a').on('click', function() { + notification.close(); + self.user_menu.on_menu_settings(); + return false; + }); + }); + $icon.appendTo(self.$('.oe_systray')); + } + }); }, destroy_content: function() { _.each(_.clone(this.getChildren()), function(el) { @@ -1252,8 +1394,9 @@ instance.web.WebClient = instance.web.Client.extend({ }, on_hashchange: function(event) { var self = this; - var state = event.getState(true); - if (!_.isEqual(this._current_state, state)) { + var stringstate = event.getState(false); + if (!_.isEqual(this._current_state, stringstate)) { + var state = event.getState(true); if(!state.action && state.menu_id) { self.menu.has_been_loaded.done(function() { self.menu.do_reload().done(function() { @@ -1265,41 +1408,49 @@ instance.web.WebClient = instance.web.Client.extend({ this.action_manager.do_load_state(state, !!this._current_state); } } - this._current_state = state; + this._current_state = stringstate; }, do_push_state: function(state) { this.set_title(state.title); delete state.title; var url = '#' + $.param(state); - this._current_state = _.clone(state); + this._current_state = $.deparam($.param(state), false); // stringify all values $.bbq.pushState(url); this.trigger('state_pushed', state); }, on_menu_action: function(options) { var self = this; - return this.rpc("/web/action/load", { action_id: options.action_id }) + return this.menu_dm.add(this.rpc("/web/action/load", { action_id: options.action_id })) .then(function (result) { - if (options.needaction) { - result.context = new instance.web.CompoundContext( - result.context, - {search_default_message_unread: true}); - } - return $.when(self.action_manager.do_action(result, { - clear_breadcrumbs: true, - action_menu_id: self.menu.current_menu, - })).fail(function() { - self.menu.open_menu(options.previous_menu_id); + return self.action_mutex.exec(function() { + if (options.needaction) { + result.context = new instance.web.CompoundContext(result.context, { + search_default_message_unread: true, + search_disable_custom_filters: true, + }); + } + var completed = $.Deferred(); + $.when(self.action_manager.do_action(result, { + clear_breadcrumbs: true, + action_menu_id: self.menu.current_menu, + })).fail(function() { + self.menu.open_menu(options.previous_menu_id); + }).always(function() { + completed.resolve(); + }); + setTimeout(function() { + completed.resolve(); + }, 2000); + // We block the menu when clicking on an element until the action has correctly finished + // loading. If something crash, there is a 2 seconds timeout before it's unblocked. + return completed; }); }); }, set_content_full_screen: function(fullscreen) { - if (fullscreen) { - $(".oe_webclient", this.$el).addClass("oe_content_full_screen"); - $("body").css({'overflow-y':'hidden'}); - } else { - $(".oe_webclient", this.$el).removeClass("oe_content_full_screen"); - $("body").css({'overflow-y':'scroll'}); - } + $(document.body).css('overflow-y', fullscreen ? 'hidden' : 'scroll'); + this.$('.oe_webclient').toggleClass( + 'oe_content_full_screen', fullscreen); }, has_uncommitted_changes: function() { var $e = $.Event('clear_uncommitted_changes'); @@ -1316,17 +1467,17 @@ instance.web.EmbeddedClient = instance.web.Client.extend({ _template: 'EmbedClient', init: function(parent, origin, dbname, login, key, action_id, options) { this._super(parent, origin); - - this.dbname = dbname; - this.login = login; - this.key = key; + this.bind_credentials(dbname, login, key); this.action_id = action_id; this.options = options || {}; }, start: function() { var self = this; return $.when(this._super()).then(function() { - return instance.session.session_authenticate(self.dbname, self.login, self.key, true).then(function() { + return self.authenticate().then(function() { + if (!self.action_id) { + return; + } return self.rpc("/web/action/load", { action_id: self.action_id }).done(function(result) { var action = result; action.flags = _.extend({ @@ -1337,11 +1488,31 @@ instance.web.EmbeddedClient = instance.web.Client.extend({ //pager : false }, self.options, action.flags || {}); - self.action_manager.do_action(action); + self.do_action(action); }); }); }); }, + + do_action: function(/*...*/) { + var am = this.action_manager; + return am.do_action.apply(am, arguments); + }, + + authenticate: function() { + var s = instance.session; + if (s.session_is_valid() && s.db === this.dbname && s.login === this.login) { + return $.when(); + } + return instance.session.session_authenticate(this.dbname, this.login, this.key, true); + }, + + bind_credentials: function(dbname, login, key) { + this.dbname = dbname; + this.login = login; + this.key = key; + }, + }); instance.web.embed = function (origin, dbname, login, key, action, options) {