summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2020-03-20 13:03:50 +0000
committerAaron Bohy <aab@odoo.com>2020-03-20 13:40:42 +0000
commitf6c06bd0b87dac11d76a3134eb61c7ef4eb59270 (patch)
tree3e029d023fa677ec9b4622d5804af57b562ed51a
parent5d86eb64aca928960b3647cd74e5f653dfdf8f8e (diff)
[FIX] web: nested x2many with non inline views
Let's assume a form view with an x2many list, containing itself an x2many field (no widget, so simply displaying the number of records). When a record of the list is clicked, a form view opens and displays the same sub x2many field, with widget many2many_tags. Both list and form views of the x2many aren't inline (thus have to be fetched on demand). Before this commit, it crashed when the user clicked on a row of the x2many list. The bug has been introduced by a9cebd5a, which wrongly removed the code handling this specific situation. At least, now we have a test attesting that this code isn't useless. Note that the diff isn't as scary as it looks like (we just added an if/else, and thus indented the former code inside the else clause). closes odoo/odoo#48116 Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
-rw-r--r--addons/web/static/src/js/views/basic/basic_view.js44
-rw-r--r--addons/web/static/tests/fields/relational_fields/field_one2many_tests.js28
2 files changed, 52 insertions, 20 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_view.js b/addons/web/static/src/js/views/basic/basic_view.js
index 6668392b823..140c338d6f6 100644
--- a/addons/web/static/src/js/views/basic/basic_view.js
+++ b/addons/web/static/src/js/views/basic/basic_view.js
@@ -138,28 +138,32 @@ var BasicView = AbstractView.extend({
// X2Many case: field is an x2many displayed as a list or
// kanban view, but the related fields haven't been loaded yet.
if ((fieldType === 'one2many' || fieldType === 'many2many')) {
- var x2mFieldInfo = record.fieldsInfo[this.viewType][name];
- var viewType = x2mFieldInfo.viewType || x2mFieldInfo.mode;
- var knownFields = Object.keys(record.data[name].fieldsInfo[record.data[name].viewType] || {});
- var newFields = Object.keys(record.data[name].fieldsInfo[viewType]);
- if (_.difference(newFields, knownFields).length) {
+ if (!('fieldsInfo' in record.data[name])) {
fieldNames.push(name);
- }
-
- if (record.data[name].viewType === 'default') {
- // Use case: x2many (tags) in x2many list views
- // When opening the x2many record form view, the
- // x2many will be reloaded but it may not have
- // the same fields (ex: tags in list and list in
- // form) so we need to merge the fieldsInfo to
- // avoid losing the initial fields (display_name)
- var fieldViews = fieldInfo.views || fieldInfo.fieldsInfo || {};
- var defaultFieldInfo = record.data[name].fieldsInfo.default;
- _.each(fieldViews, function (fieldView) {
- _.each(fieldView.fieldsInfo, function (x2mFieldInfo) {
- _.defaults(x2mFieldInfo, defaultFieldInfo);
+ } else {
+ var x2mFieldInfo = record.fieldsInfo[this.viewType][name];
+ var viewType = x2mFieldInfo.viewType || x2mFieldInfo.mode;
+ var knownFields = Object.keys(record.data[name].fieldsInfo[record.data[name].viewType] || {});
+ var newFields = Object.keys(record.data[name].fieldsInfo[viewType]);
+ if (_.difference(newFields, knownFields).length) {
+ fieldNames.push(name);
+ }
+
+ if (record.data[name].viewType === 'default') {
+ // Use case: x2many (tags) in x2many list views
+ // When opening the x2many record form view, the
+ // x2many will be reloaded but it may not have
+ // the same fields (ex: tags in list and list in
+ // form) so we need to merge the fieldsInfo to
+ // avoid losing the initial fields (display_name)
+ var fieldViews = fieldInfo.views || fieldInfo.fieldsInfo || {};
+ var defaultFieldInfo = record.data[name].fieldsInfo.default;
+ _.each(fieldViews, function (fieldView) {
+ _.each(fieldView.fieldsInfo, function (x2mFieldInfo) {
+ _.defaults(x2mFieldInfo, defaultFieldInfo);
+ });
});
- });
+ }
}
}
// Many2one: context is not the same between the different views
diff --git a/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js b/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js
index e93dc2f39ca..4bd23d0d76b 100644
--- a/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js
+++ b/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js
@@ -5508,6 +5508,34 @@ QUnit.module('fields', {}, function () {
form.destroy();
});
+ QUnit.test('nested x2many (non inline views and no widget on inner x2many in list)', async function (assert) {
+ assert.expect(5);
+
+ this.data.partner.records[0].p = [1];
+ const form = await createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: '<form><field name="p"/></form>',
+ archs: {
+ 'partner,false,list': '<tree><field name="turtles"/></tree>',
+ 'partner,false,form': '<form><field name="turtles" widget="many2many_tags"/></form>',
+ },
+ res_id: 1,
+ });
+
+ assert.containsOnce(form, '.o_data_row');
+ assert.strictEqual(form.$('.o_data_row').text(), '1 record');
+
+ await testUtils.dom.click(form.$('.o_data_row'));
+
+ assert.containsOnce(document.body, '.modal .o_form_view');
+ assert.containsOnce(document.body, '.modal .o_form_view .o_field_many2manytags .badge');
+ assert.strictEqual($('.modal .o_field_many2manytags').text().trim(), 'donatello');
+
+ form.destroy();
+ });
+
QUnit.test('one2many (who contains display_name) with tree view and without form view', async function (assert) {
assert.expect(1);