From 604bd9fa4da689e3162a295ecd2959a764bd4eef Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 5 Sep 2012 14:35:32 +0200 Subject: [PATCH 01/11] [WIP] Notification on do_action and on_mode_switch bzr revid: fme@openerp.com-20120905123532-oskxl7srmoabkqr5 --- addons/web/static/src/js/chrome.js | 3 +-- addons/web/static/src/js/view_form.js | 5 ++++ addons/web/static/src/js/views.js | 38 ++++++++++++++++++++------- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 736e10875f6..3dd7672287f 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1101,8 +1101,7 @@ instance.web.WebClient = instance.web.Client.extend({ if (options.needaction) { action.context.search_default_needaction_pending = true; } - self.action_manager.clear_breadcrumbs(); - self.action_manager.do_action(action); + self.action_manager.do_action(action, null, true); }); }, do_action: function(action) { diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index f65da67d8fb..e6bbb664eaf 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -92,6 +92,11 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM self.on("change:actual_mode", self, self.init_pager); self.init_pager(); }); + this.on('about_to_destroy', this, function(e) { + if (!this.can_be_discarded()) { + e.preventDefault(); + } + }); }, destroy: function() { _.each(this.get_widgets(), function(w) { diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 95693ca9c50..20f7b12c0ac 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -113,6 +113,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ while (this.breadcrumbs.length) { this.remove_breadcrumb(0); } + this.inner_widget = null; }, remove_breadcrumb: function(index) { var item = this.breadcrumbs.splice(index, 1)[0]; @@ -208,14 +209,14 @@ instance.web.ActionManager = instance.web.Widget.extend({ } }); }, - do_action: function(action, on_close) { + do_action: function(action, on_close, clear_breadcrumbs) { if (_.isString(action) && instance.web.client_actions.contains(action)) { var action_client = { type: "ir.actions.client", tag: action }; - return this.do_action(action_client); + return this.do_action(action_client, on_close, clear_breadcrumbs); } else if (_.isNumber(action) || _.isString(action)) { var self = this; return self.rpc("/web/action/load", { action_id: action }, function(result) { - self.do_action(result.result, on_close); + self.do_action(result.result, on_close, clear_breadcrumbs); }); } if (!action.type) { @@ -237,14 +238,23 @@ instance.web.ActionManager = instance.web.Widget.extend({ console.error("Action manager can't handle action of type " + action.type, action); return null; } - return this[type](action, on_close); + return this[type](action, on_close, clear_breadcrumbs); }, null_action: function() { this.dialog_stop(); this.clear_breadcrumbs(); }, - ir_actions_common: function(action, on_close) { + ir_actions_common: function(action, on_close, clear_breadcrumbs) { var self = this, klass, widget, post_process; + if (this.inner_widget && (action.type === 'ir.actions.client' || action.target !== 'new')) { + var $e = $.Event("about_to_destroy"); + this.inner_widget.trigger("about_to_destroy", $e); + if ($e.isDefaultPrevented()) { + return; + } else if (clear_breadcrumbs) { + this.clear_breadcrumbs(); + } + } if (action.type === 'ir.actions.client') { var ClientWidget = instance.web.client_actions.get_object(action.tag); widget = new ClientWidget(this, action.params); @@ -287,17 +297,17 @@ instance.web.ActionManager = instance.web.Widget.extend({ this.inner_widget.appendTo(this.$el); } }, - ir_actions_act_window: function (action, on_close) { + ir_actions_act_window: function (action, on_close, clear_breadcrumbs) { var self = this; if (action.target !== 'new') { if(action.menu_id) { this.dialog_stop(); return this.getParent().do_action(action, function () { instance.webclient.menu.open_menu(action.menu_id); - }); + }, clear_breadcrumbs); } } - return this.ir_actions_common(action, on_close); + return this.ir_actions_common(action, on_close, clear_breadcrumbs); }, ir_actions_client: function (action, on_close) { return this.ir_actions_common(action, on_close); @@ -314,7 +324,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ action_id: action.id, context: action.context || {} }).then(function (action) { - self.do_action(action, on_closed) + self.do_action(action, on_closed, clear_breadcrumbs) }); }, ir_actions_report_xml: function(action, on_closed) { @@ -412,8 +422,10 @@ instance.web.ViewManager = instance.web.Widget.extend({ var self = this; var view = this.views[view_type]; var view_promise; - if(!view) + var form = this.views['form']; + if (!view || (form && form.controller && !form.controller.can_be_discarded())) { return $.Deferred().reject(); + } if (!no_store) { this.views_history.push(view_type); @@ -472,6 +484,12 @@ instance.web.ViewManager = instance.web.Widget.extend({ } var controller = new viewclass(this, this.dataset, view.view_id, options); + if (view_type === 'form') { + this.on('about_to_destroy', this, function(e) { + controller.trigger('about_to_destroy', e); + }); + } + controller.on('history_back', this, function() { var am = self.getParent(); if (am && am.trigger) { From b675eb40de439b126fb4dffa00fde0c883f5f7b0 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 5 Sep 2012 15:45:53 +0200 Subject: [PATCH 02/11] [ADD] Revert menu in case do_action fails bzr revid: fme@openerp.com-20120905134553-k6ryuelp5fhsw6z9 --- addons/web/static/src/js/chrome.js | 17 ++++++++++------- addons/web/static/src/js/views.js | 10 +++++----- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 3dd7672287f..3180c21f88e 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -731,6 +731,8 @@ instance.web.Menu = instance.web.Widget.extend({ * @param {Number} id database id of the terminal menu to select */ open_menu: function (id) { + this.current_menu = id; + this.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); @@ -803,16 +805,15 @@ instance.web.Menu = instance.web.Widget.extend({ } } } - this.open_menu(id); - this.current_menu = id; - this.session.active_id = id; if (action_id) { this.trigger('menu_click', { action_id: action_id, needaction: needaction, - id: id + id: id, + previous_menu_id: this.current_menu // Here we don't know if action will fail (in which case we have to revert menu) }, $item); } + this.open_menu(id); }, /** * Jquery event handler for menu click @@ -1095,13 +1096,15 @@ instance.web.WebClient = instance.web.Client.extend({ }, on_menu_action: function(options) { var self = this; - this.rpc("/web/action/load", { action_id: options.action_id }) - .then(function (result) { + return this.rpc("/web/action/load", { action_id: options.action_id }) + .pipe(function (result) { var action = result.result; if (options.needaction) { action.context.search_default_needaction_pending = true; } - self.action_manager.do_action(action, null, true); + return $.when(self.action_manager.do_action(action, null, true)).fail(function() { + self.menu.open_menu(options.previous_menu_id); + }); }); }, do_action: function(action) { diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 20f7b12c0ac..2f015dab7a0 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -215,13 +215,13 @@ instance.web.ActionManager = instance.web.Widget.extend({ return this.do_action(action_client, on_close, clear_breadcrumbs); } else if (_.isNumber(action) || _.isString(action)) { var self = this; - return self.rpc("/web/action/load", { action_id: action }, function(result) { - self.do_action(result.result, on_close, clear_breadcrumbs); + return self.rpc("/web/action/load", { action_id: action }).pipe(function(result) { + return self.do_action(result.result, on_close, clear_breadcrumbs); }); } if (!action.type) { console.error("No type for action", action); - return null; + return $.Deferred().reject(); } var type = action.type.replace(/\./g,'_'); var popup = action.target === 'new'; @@ -236,7 +236,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ }, action.flags || {}); if (!(type in this)) { console.error("Action manager can't handle action of type " + action.type, action); - return null; + return $.Deferred().reject(); } return this[type](action, on_close, clear_breadcrumbs); }, @@ -250,7 +250,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ var $e = $.Event("about_to_destroy"); this.inner_widget.trigger("about_to_destroy", $e); if ($e.isDefaultPrevented()) { - return; + return $.Deferred().reject(); } else if (clear_breadcrumbs) { this.clear_breadcrumbs(); } From 404acf222cb2b097c8da608e6bfd24ed494069a5 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 5 Sep 2012 17:03:41 +0200 Subject: [PATCH 03/11] [ADD] Implement dirty form check at the breadcrumbs level bzr revid: fme@openerp.com-20120905150341-1188kodv77bys922 --- addons/web/static/src/js/views.js | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 2f015dab7a0..0d8430d53ee 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -101,7 +101,9 @@ instance.web.ActionManager = instance.web.Widget.extend({ select_breadcrumb: function(index, subindex) { for (var i = this.breadcrumbs.length - 1; i >= 0; i--) { if (i > index) { - this.remove_breadcrumb(i); + if (this.remove_breadcrumb(i) === false) { + return false; + } } } var item = this.breadcrumbs[index]; @@ -110,10 +112,11 @@ instance.web.ActionManager = instance.web.Widget.extend({ return true; }, clear_breadcrumbs: function() { - while (this.breadcrumbs.length) { - this.remove_breadcrumb(0); + for (var i = this.breadcrumbs.length - 1; i >= 0; i--) { + if (this.remove_breadcrumb(0) === false) { + break; + } } - this.inner_widget = null; }, remove_breadcrumb: function(index) { var item = this.breadcrumbs.splice(index, 1)[0]; @@ -122,9 +125,19 @@ instance.web.ActionManager = instance.web.Widget.extend({ return item.widget === it.widget; }); if (!dups.length) { - item.destroy(); + var $e = $.Event("about_to_destroy"); + item.widget.trigger("about_to_destroy", $e); + if ($e.isDefaultPrevented()) { + this.inner_widget = item.widget; + this.breadcrumbs.splice(index, 0, item); + return false; + } else { + item.destroy(); + } } } + var last_widget = this.breadcrumbs.slice(-1)[0]; + this.inner_widget = last_widget && last_widget.widget; }, get_title: function() { var titles = []; From 2cf1f7a7a6312066a8007eca53fe05039e416cf3 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 5 Sep 2012 17:20:30 +0200 Subject: [PATCH 04/11] [ADD] Added dirty form notification on on_logout bzr revid: fme@openerp.com-20120905152030-qfrkrwg4k1srxtix --- addons/web/static/src/js/chrome.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 3180c21f88e..21b0c050365 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1049,11 +1049,15 @@ instance.web.WebClient = instance.web.Client.extend({ }, on_logout: function() { var self = this; - this.session.session_logout().then(function () { - $(window).unbind('hashchange', self.on_hashchange); - self.do_push_state({}); - window.location.reload(); - }); + var $e = $.Event("about_to_destroy"); + this.action_manager.inner_widget.trigger("about_to_destroy", $e); + if (!$e.isDefaultPrevented()) { + this.session.session_logout().then(function () { + $(window).unbind('hashchange', self.on_hashchange); + self.do_push_state({}); + window.location.reload(); + }); + } }, bind_hashchange: function() { var self = this; From 51094bd0de30eac3363bed606e0def2d9477e7c4 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 5 Sep 2012 17:23:26 +0200 Subject: [PATCH 05/11] [IMP] Make footer's "Powered by OpenERP" an external link target _blank bzr revid: fme@openerp.com-20120905152326-3z1b1imtm3mis8ff --- addons/web/static/src/xml/base.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index d206c538e1c..7319865688c 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -79,7 +79,7 @@ @@ -410,7 +410,7 @@
From a01a27e4806a078a4b0258c102340a41fc9b94ef Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 5 Sep 2012 17:41:21 +0200 Subject: [PATCH 06/11] [IMP] Make the logo trigger client action 'home' instead of a link bzr revid: fme@openerp.com-20120905154121-8lokz9x0x7fraidd --- addons/web/static/src/js/chrome.js | 3 +++ addons/web/static/src/xml/base.xml | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 21b0c050365..398e08f6887 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -964,6 +964,9 @@ instance.web.WebClient = instance.web.Client.extend({ start: function() { var self = this; return $.when(this._super()).pipe(function() { + self.$el.on('click', '.oe_logo', function() { + self.action_manager.do_action('home'); + }); if (jQuery.param !== undefined && jQuery.deparam(jQuery.param.querystring()).kitten !== undefined) { $("body").addClass("kitten-mode-activated"); if ($.blockUI) { diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 7319865688c..a96ec8937a1 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -404,10 +404,7 @@ - - d.url = '/' + (window.location.search || ''); - - +