Skip to content
Snippets Groups Projects
Commit b096915d authored by Aaron Bohy's avatar Aaron Bohy
Browse files

[FIX] board: stop the propagation of custom events

Recently, rev. 5b3cb812 added a new custom event ('update_filters')
handler to the ActionManager, and rev. 69c9500e added an option
('keepSearchView') to doAction (which can be called by triggering
up event 'do_action').

Both events ('update_filters' and 'do_action') can be triggered by
controllers, and when those controllers were in the dashboard, a
crash occured when they triggered those events. In particular, they
are triggered by the new 'web_dashboard' view, respectively when
clicking on an aggregate and when clicking on the subview button to
open it full screen.

The crashes occurred because the events weren't intercepted by the
dashboard, so they bubbled up to the ActionManager which couldn't
handle the requests properly as it wasn't aware of those sub
controllers.

As there is no search view in the dashboard, the 'update_filters'
event simply needs to be stopped (we can't handle such a request
in the dashboard), and for the 'do_action' event, the
'keepSearchView' option must be forced to false as there is no
search view to keep (we thus force the ActionManager to create a
new one).
parent 1d92bb41
No related branches found
No related tags found
No related merge requests found
......@@ -117,7 +117,9 @@ var BoardController = FormController.extend({
var BoardRenderer = FormRenderer.extend({
custom_events: _.extend({}, FormRenderer.prototype.custom_events, {
do_action: '_onDoAction',
env_updated: '_onEnvUpdated',
update_filters: '_onUpdateFilters',
}),
events: _.extend({}, FormRenderer.prototype.events, {
'click .oe_dashboard_column .oe_fold': '_onFoldClick',
......@@ -332,10 +334,23 @@ var BoardRenderer = FormRenderer.extend({
});
},
/**
* Stops the propagation of 'update_env' events triggered by the controllers
* Intercepts (without stopping) 'do_action' events to force the
* 'keepSearchView' option to false, as the dashboard action has no search
* view, and thus there is no search view that could be re-used for the
* action to execute (a new one will be created instead).
*
* @private
* @param {OdooEvent} event
*/
_onDoAction: function (event) {
if (event.data.options) {
event.data.options.keepSearchView = false;
}
},
/**
* Stops the propagation of 'env_updated' events triggered by the controllers
* instantiated by the dashboard.
*
* @override
* @private
*/
_onEnvUpdated: function (event) {
......@@ -360,6 +375,17 @@ var BoardRenderer = FormRenderer.extend({
$action.find('.oe_content').toggle();
this.trigger_up('save_dashboard');
},
/**
* Stops the propagation of 'update_filters' events triggered by the
* controllers instantiated by the dashboard to prevent them from
* interfering with the ActionManager.
*
* @private
* @param {OdooEvent} event
*/
_onUpdateFilters: function (event) {
event.stopPropagation();
},
});
var BoardView = FormView.extend({
......
......@@ -3,6 +3,7 @@ odoo.define('board.dashboard_tests', function (require) {
var BoardView = require('board.BoardView');
var ListController = require('web.ListController');
var testUtils = require('web.test_utils');
var createView = testUtils.createView;
......@@ -455,4 +456,59 @@ QUnit.test('clicking on a kanban\'s button should trigger the action', function
form.destroy();
});
QUnit.test('dashboard intercepts custom events triggered by sub controllers', function (assert) {
assert.expect(4);
// we patch the ListController to force it to trigger the custom events that
// we want the dashboard to intercept (to stop them or to tweak their data)
testUtils.patch(ListController, {
start: function () {
this.trigger_up('update_filters');
this.trigger_up('env_updated');
this.do_action({}, {keepSearchView: true});
},
});
var board = createView({
View: BoardView,
model: 'board',
data: this.data,
arch: '<form string="My Dashboard">' +
'<board style="2-1">' +
'<column>' +
'<action context="{}" view_mode="list" string="ABC" name="51" domain="[]"></action>' +
'</column>' +
'</board>' +
'</form>',
mockRPC: function (route) {
if (route === '/web/action/load') {
return $.when({res_model: 'partner', views: [[false, 'list']]});
}
return this._super.apply(this, arguments);
},
archs: {
'partner,false,list': '<tree string="Partner"/>',
},
intercepts: {
do_action: function (ev) {
assert.strictEqual(ev.data.options.keepSearchView, false,
"the 'keepSearchView' options should have been set to false");
},
env_updated: function (ev) {
assert.strictEqual(ev.target.modelName, 'board',
"env_updated event should be triggered by the dashboard itself");
assert.step('env_updated');
},
update_filters: assert.step.bind(assert, 'update_filters'),
},
});
assert.verifySteps([
'env_updated', // triggered by the dashboard itself
]);
testUtils.unpatch(ListController);
board.destroy();
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment