Before this commit, the way mode was handled was not optimal. The end result was correct (the widget were properly created/displayed in edit/readonly as required), but useless work was done. In particular, if we have list/x2manys with widgets and modifiers, it could happen that widgets were created in edit mode, then destroyed and recreated in readonly mode. This could happen in some important views, for example, any view with a field many2many_tags with a readonly modifiers (pretty much all views handling taxes) In this commit, we add a 'editable' attribute to list renderer. This is necessary, because the list renderer is not actually editable when it is in a x2many in a form view which is in readonly mode. Also, we need to manage the distinction between the fact that a list view is editable, and the fact that some widgets are created in edit and other in readonly mode, depending on modifiers, and on which line is being edited. We also add a benchmark (courtesy of CHM) to be able to measure the performance impact of edit/readonly/onchange in a larger form view. Before this commit, running this form benchmark on my machine gave a number of 0.4 op/sec, and after, it increases to 1.26 op/sec, so a pretty large improvement.
95 lines
3.1 KiB
JavaScript
95 lines
3.1 KiB
JavaScript
odoo.define('web.list_benchmarks', function (require) {
|
|
"use strict";
|
|
|
|
var FormView = require('web.FormView');
|
|
var testUtils = require('web.test_utils');
|
|
|
|
var createView = testUtils.createView;
|
|
|
|
QUnit.module('Form View', {
|
|
beforeEach: function () {
|
|
this.data = {
|
|
foo: {
|
|
fields: {
|
|
many2many: { string: "bar", type: "many2many", relation: 'bar'},
|
|
},
|
|
records: [
|
|
{ id: 1, many2many: []},
|
|
],
|
|
onchanges: {}
|
|
},
|
|
bar: {
|
|
fields: {
|
|
char: {string: "char", type: "char"},
|
|
many2many: { string: "pokemon", type: "many2many", relation: 'pokemon'},
|
|
},
|
|
records: [],
|
|
onchanges: {}
|
|
},
|
|
pokemon: {
|
|
fields: {
|
|
name: {string: "Name", type: "char"},
|
|
},
|
|
records: [],
|
|
onchanges: {}
|
|
},
|
|
};
|
|
this.arch = null;
|
|
this.run = function (assert, done, cb) {
|
|
var data = this.data;
|
|
var arch = this.arch;
|
|
var viewOptions = this.viewOptions;
|
|
new Benchmark.Suite({})
|
|
.add('form', function () {
|
|
var list = createView({
|
|
View: FormView,
|
|
model: 'foo',
|
|
data: data,
|
|
arch: arch,
|
|
res_id: 1,
|
|
});
|
|
if (cb) {
|
|
cb(list);
|
|
}
|
|
list.destroy();
|
|
})
|
|
.on('cycle', function(event) {
|
|
assert.ok(true, String(event.target));
|
|
})
|
|
.on('complete', done)
|
|
.run({ 'async': true });
|
|
};
|
|
}
|
|
}, function () {
|
|
QUnit.test('x2many with 250 rows, 2 fields (with many2many_tags, and modifiers), onchanges, and edition', function (assert) {
|
|
var done = assert.async();
|
|
assert.expect(1);
|
|
|
|
this.data.foo.onchanges.many2many = function (obj) {
|
|
obj.many2many = [5].concat(obj.many2many);
|
|
};
|
|
for (var i = 2; i < 500; i) {
|
|
this.data.bar.records.push({
|
|
id: i,
|
|
char: "automated data",
|
|
});
|
|
this.data.foo.records[0].many2many.push(i);
|
|
}
|
|
this.arch =
|
|
'<form string="Partners">'
|
|
'<field name="many2many">'
|
|
'<tree editable="top" limit="250">'
|
|
'<field name="char"/>'
|
|
'<field name="many2many" widget="many2many_tags" attrs="{\'readonly\': [(\'char\', \'==\', \'toto\')]}"/>'
|
|
'</tree>'
|
|
'</field>'
|
|
'</form>';
|
|
this.run(assert, done, function (form) {
|
|
form.$buttons.find('.o_form_button_edit').click();
|
|
form.$('.o_data_cell:first').click();
|
|
form.$('input:first').val("tralala").trigger('input');
|
|
});
|
|
});
|
|
});
|
|
|
|
}); |