[FIX] board: handle actions with no view_mode

The view_mode attribute is automatically set to the 'action' nodes
when the action is added to the dashboard using the 'Add to
dashboard' button in the searchview. However, other dashboard views
can be written by hand (see openacademy tutorial), and in this
case, we don't want to hardcode action's params (like context or
domain), as the dashboard can directly retrieve them from the
action. Same applies for the view_type, as the first view of the
action can be used, by default.

Before this rev., the second usecase wasn't handled, and it crashed
when no view_mode was specified. This rev. also ensure that the
context and domain are correctly retrieved from the action.

Closes #24088

closes odoo/odoo#27517
This commit is contained in:
Aaron Bohy
2018-10-08 09:19:21 +00:00
parent 078b31dc7f
commit a69f117bbf
2 changed files with 63 additions and 8 deletions
+12 -8
View File
@@ -9,6 +9,7 @@ var Domain = require('web.Domain');
var FormController = require('web.FormController');
var FormRenderer = require('web.FormRenderer');
var FormView = require('web.FormView');
var pyUtils = require('web.pyeval'); // do not forwardport this to 12.0
var viewRegistry = require('web.view_registry');
var _t = core._t;
@@ -243,7 +244,6 @@ FormRenderer.include({
*/
_createController: function (params) {
var self = this;
var context = params.context.eval();
return this._rpc({
route: '/web/action/load',
params: {action_id: params.actionID}
@@ -253,18 +253,22 @@ FormRenderer.include({
// the action does not exist anymore
return $.when();
}
var rawContext = new Context(params.context, action.context);
var context = pyUtils.eval('context', rawContext);
var domain = params.domain || pyUtils.eval('domain', action.domain || '[]', action.context);
var viewType = params.viewType || action.views[0][1];
var view = _.find(action.views, function (descr) {
return descr[1] === params.viewType;
}) || [false, params.viewType];
return self.loadViews(action.res_model, params.context, [view])
return descr[1] === viewType;
}) || [false, viewType];
return self.loadViews(action.res_model, rawContext, [view]) // use context instead of rawContext when forwardported to > 11.0
.then(function (viewsInfo) {
var viewInfo = viewsInfo[params.viewType];
var View = viewRegistry.get(params.viewType);
var viewInfo = viewsInfo[viewType];
var View = viewRegistry.get(viewType);
var view = new View(viewInfo, {
action: action,
context: context,
domain: params.domain,
groupBy: context.group_by,
domain: domain,
groupBy: context.group_by || [],
modelName: action.res_model,
hasSelectors: false,
});
@@ -188,6 +188,57 @@ QUnit.test('basic functionality, with one sub action', function (assert) {
form.destroy();
});
QUnit.test('can render an action without view_mode attribute', function (assert) {
// The view_mode attribute is automatically set to the 'action' nodes when
// the action is added to the dashboard using the 'Add to dashboard' button
// in the searchview. However, other dashboard views can be written by hand
// (see openacademy tutorial), and in this case, we don't want hardcode
// action's params (like context or domain), as the dashboard can directly
// retrieve them from the action. Same applies for the view_type, as the
// first view of the action can be used, by default.
assert.expect(2);
var form = createView({
View: FormView, // replace by BoardView when forwarported to saas-11.3
model: 'board',
data: this.data,
arch: '<form string="My Dashboard">' +
'<board style="2-1">' +
'<column>' +
'<action string="ABC" name="51" context="{\'a\': 1}"></action>' +
'</column>' +
'</board>' +
'</form>',
archs: {
'partner,4,list':
'<tree string="Partner"><field name="foo"/></tree>',
},
mockRPC: function (route, args) {
if (route === '/board/static/src/img/layout_1-1-1.png') {
return $.when();
}
if (route === '/web/action/load') {
return $.when({
context: '{"b": 2}',
domain: '[["foo", "=", "yop"]]',
res_model: 'partner',
views: [[4, 'list'], [false, 'form']],
});
}
if (route === '/web/dataset/search_read') {
assert.deepEqual(args.domain, [['foo', '=', 'yop']],
"should use the domain of the action");
}
return this._super.apply(this, arguments);
},
});
assert.strictEqual(form.$('.oe_action:contains(ABC) .o_list_view').length, 1,
"the list view (first view of action) should have been rendered correctly");
form.destroy();
});
QUnit.test('can sort a sub list', function (assert) {
assert.expect(2);