[FIX] web: resequence work w/ discardable lines
In 11.0 091c86c21 introduced the unselection of lines when line are
resequenced to solve some issue.
There seems to be a related issue in the following use case if:
- the one2many has a handle field
- the lines have same sequence (eg. adding 2 o2m lines on new record)
- there is an invalid o2m line (eg. empty line and required field)
- without blurring, a valid line is moved
then this happen:
- the sequence of lines are computed
- the invalid line is removed
- the computed sequence of lines are applied
=> this break next onchange, because we try to apply an onchange to data
that does not exist anymore (the invalid line).
With this changeset, the invalid lines are discarded before sequences
are computed so the computation is still correct before being applied.
Without the change, the added test fails with:
5. one onchange happens when lines are resequenced (expect: 3, res: 2)
7. one onchange happens when a line is added (expect: 4, res: 2)
8. onchange worked there is 2 lines (expect: 2, res: 1)
opw-1966589
closes #33591
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
@@ -549,48 +549,48 @@ ListRenderer.include({
|
||||
_resequence: function (event, ui) {
|
||||
var self = this;
|
||||
var movedRecordID = ui.item.data('id');
|
||||
var rows = this.state.data;
|
||||
var row = _.findWhere(rows, {id: movedRecordID});
|
||||
var index0 = rows.indexOf(row);
|
||||
var index1 = ui.item.index();
|
||||
var lower = Math.min(index0, index1);
|
||||
var upper = Math.max(index0, index1) + 1;
|
||||
self.unselectRow().then(function () {
|
||||
var rows = self.state.data;
|
||||
var row = _.findWhere(rows, {id: movedRecordID});
|
||||
var index0 = rows.indexOf(row);
|
||||
var index1 = ui.item.index();
|
||||
var lower = Math.min(index0, index1);
|
||||
var upper = Math.max(index0, index1) + 1;
|
||||
|
||||
var order = _.findWhere(self.state.orderedBy, {name: self.handleField});
|
||||
var asc = !order || order.asc;
|
||||
var reorderAll = false;
|
||||
var sequence = (asc ? -1 : 1) * Infinity;
|
||||
var order = _.findWhere(self.state.orderedBy, {name: self.handleField});
|
||||
var asc = !order || order.asc;
|
||||
var reorderAll = false;
|
||||
var sequence = (asc ? -1 : 1) * Infinity;
|
||||
|
||||
// determine if we need to reorder all lines
|
||||
_.each(rows, function (row, index) {
|
||||
if ((index < lower || index >= upper) &&
|
||||
((asc && sequence >= row.data[self.handleField]) ||
|
||||
(!asc && sequence <= row.data[self.handleField]))) {
|
||||
reorderAll = true;
|
||||
}
|
||||
sequence = row.data[self.handleField];
|
||||
});
|
||||
// determine if we need to reorder all lines
|
||||
_.each(rows, function (row, index) {
|
||||
if ((index < lower || index >= upper) &&
|
||||
((asc && sequence >= row.data[self.handleField]) ||
|
||||
(!asc && sequence <= row.data[self.handleField]))) {
|
||||
reorderAll = true;
|
||||
}
|
||||
sequence = row.data[self.handleField];
|
||||
});
|
||||
|
||||
if (reorderAll) {
|
||||
rows = _.without(rows, row);
|
||||
rows.splice(index1, 0, row);
|
||||
} else {
|
||||
rows = rows.slice(lower, upper);
|
||||
rows = _.without(rows, row);
|
||||
if (index0 > index1) {
|
||||
rows.unshift(row);
|
||||
if (reorderAll) {
|
||||
rows = _.without(rows, row);
|
||||
rows.splice(index1, 0, row);
|
||||
} else {
|
||||
rows.push(row);
|
||||
rows = rows.slice(lower, upper);
|
||||
rows = _.without(rows, row);
|
||||
if (index0 > index1) {
|
||||
rows.unshift(row);
|
||||
} else {
|
||||
rows.push(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sequences = _.pluck(_.pluck(rows, 'data'), self.handleField);
|
||||
var rowIDs = _.pluck(rows, 'id');
|
||||
var sequences = _.pluck(_.pluck(rows, 'data'), self.handleField);
|
||||
var rowIDs = _.pluck(rows, 'id');
|
||||
|
||||
if (!asc) {
|
||||
rowIDs.reverse();
|
||||
}
|
||||
this.unselectRow().then(function () {
|
||||
if (!asc) {
|
||||
rowIDs.reverse();
|
||||
}
|
||||
self.trigger_up('resequence', {
|
||||
rowIDs: rowIDs,
|
||||
offset: _.min(sequences),
|
||||
|
||||
@@ -6694,5 +6694,66 @@ QUnit.module('Views', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('resequence list lines when discardable lines are present', function (assert) {
|
||||
assert.expect(8);
|
||||
|
||||
var onchangeNum = 0;
|
||||
|
||||
this.data.partner.onchanges = {
|
||||
p: function (obj) {
|
||||
onchangeNum++;
|
||||
obj.foo = obj.p.length.toString();
|
||||
},
|
||||
};
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form>' +
|
||||
'<field name="foo"/>' +
|
||||
'<field name="p"/>' +
|
||||
'</form>',
|
||||
archs: {
|
||||
'partner,false,list':
|
||||
'<tree editable="bottom">' +
|
||||
'<field name="int_field" widget="handle"/>' +
|
||||
'<field name="display_name" required="1"/>' +
|
||||
'</tree>',
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(onchangeNum, 1, "one onchange happens when form is opened");
|
||||
assert.strictEqual(form.$('[name="foo"]').val(), "0", "onchange worked there is 0 line");
|
||||
|
||||
// Add one line
|
||||
form.$('.o_field_x2many_list_row_add a').click();
|
||||
form.$('.o_field_one2many input:first').focus();
|
||||
form.$('.o_field_one2many input:first').val('first line').trigger('input');
|
||||
form.$('input[name="foo"]').click();
|
||||
assert.strictEqual(onchangeNum, 2, "one onchange happens when a line is added");
|
||||
assert.strictEqual(form.$('[name="foo"]').val(), "1", "onchange worked there is 1 line");
|
||||
|
||||
// Drag and drop second line before first one (with 1 draft and invalid line)
|
||||
form.$('.o_field_x2many_list_row_add a').click();
|
||||
testUtils.dragAndDrop(
|
||||
form.$('.ui-sortable-handle').eq(0),
|
||||
form.$('.o_data_row').last(),
|
||||
{position: 'bottom'}
|
||||
);
|
||||
assert.strictEqual(onchangeNum, 3, "one onchange happens when lines are resequenced")
|
||||
assert.strictEqual(form.$('[name="foo"]').val(), "1", "onchange worked there is 1 line");
|
||||
|
||||
// Add a second line
|
||||
form.$('.o_field_x2many_list_row_add a').click();
|
||||
form.$('.o_field_one2many input:first').focus();
|
||||
form.$('.o_field_one2many input:first').val('second line').trigger('input');
|
||||
form.$('input[name="foo"]').click();
|
||||
assert.strictEqual(onchangeNum, 4, "one onchange happens when a line is added");
|
||||
assert.strictEqual(form.$('[name="foo"]').val(), "2", "onchange worked there is 2 lines");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user