[FIX] web: can edit SelectionField in draggable kanban

Before this commit, if a SelectionField was used in a kanban view
alongside the HandleField (enabling re-sequencing, i.e. drag&drop),
the "select" element couldn't be edited. This is because the d&d
feature calls preventDefault on almost all "pointerdown" events
occuring in the card, and the "pointerdown" event is the one that
opens the select.

There's no usecase in 17.0, but there's one in master, in the
product document kanban view.

We fix this in 17.0 which is the version that introduced the kanban
version of the SelectionField.

closes odoo/odoo#155827

Signed-off-by: Julien Mougenot (jum) <jum@odoo.com>
This commit is contained in:
Aaron Bohy
2024-02-29 14:07:49 +00:00
parent 24d6d15efb
commit 0dfee1606b
3 changed files with 61 additions and 22 deletions
@@ -72,15 +72,24 @@ export class SelectionField extends Component {
switch (this.type) {
case "many2one":
if (value === false) {
this.props.record.update({ [this.props.name]: false }, { save: this.props.autosave });
this.props.record.update(
{ [this.props.name]: false },
{ save: this.props.autosave }
);
} else {
this.props.record.update({
[this.props.name]: this.options.find((option) => option[0] === value),
}, { save: this.props.autosave });
this.props.record.update(
{
[this.props.name]: this.options.find((option) => option[0] === value),
},
{ save: this.props.autosave }
);
}
break;
case "selection":
this.props.record.update({ [this.props.name]: value }, { save: this.props.autosave });
this.props.record.update(
{ [this.props.name]: value },
{ save: this.props.autosave }
);
break;
}
}
@@ -100,7 +109,7 @@ export const selectionField = {
};
if (viewType === "kanban") {
props.readonly = dynamicInfo.readonly;
};
}
return props;
},
};
@@ -97,7 +97,7 @@ export class KanbanRenderer extends Component {
// Params
ref: this.rootRef,
elements: ".o_draggable",
ignore: ".dropdown",
ignore: ".dropdown,select",
groups: () => this.props.list.isGrouped && ".o_kanban_group",
connectGroups: () => this.canMoveRecords,
cursor: "move",
@@ -405,7 +405,7 @@ QUnit.module("Fields", (hooks) => {
[...target.querySelectorAll(".o_field_widget[name='color'] option")].map(
(option) => option.value
),
["false", "\"red\"", "\"black\""]
["false", '"red"', '"black"']
);
});
@@ -440,13 +440,13 @@ QUnit.module("Fields", (hooks) => {
QUnit.test(
"SelectionField don't open form view on click in kanban view",
async function (assert) {
assert.expect(1);
assert.expect(1);
await makeView({
type: "kanban",
resModel: "partner",
serverData,
arch: `
await makeView({
type: "kanban",
resModel: "partner",
serverData,
arch: `
<kanban>
<templates>
<t t-name="kanban-box">
@@ -456,15 +456,16 @@ QUnit.module("Fields", (hooks) => {
</t>
</templates>
</kanban>`,
domain: [["id", "=", 1]],
selectRecord: () => {
assert.step("selectRecord");
},
});
domain: [["id", "=", 1]],
selectRecord: () => {
assert.step("selectRecord");
},
});
await click(target, ".o_field_widget[name='color'] select");
assert.verifySteps([]);
});
await click(target, ".o_field_widget[name='color'] select");
assert.verifySteps([]);
}
);
QUnit.test("SelectionField is disabled if field readonly", async function (assert) {
assert.expect(1);
@@ -523,4 +524,33 @@ QUnit.module("Fields", (hooks) => {
"field should be readonly"
);
});
QUnit.test("SelectionField in kanban view with handle widget", async function (assert) {
// When records are draggable, most pointerdown events are default prevented. This test
// comes with a fix that blacklists "select" elements, i.e. pointerdown events on such
// elements aren't default prevented, because if they were, the select element can't be
// opened. The test is a bit artificial but there's no other way to test the scenario, as
// using editSelect simply triggers a "change" event, which obviously always works.
await makeView({
type: "kanban",
resModel: "partner",
serverData,
arch: `
<kanban>
<field name="int_field" widget="handle"/>
<templates>
<t t-name="kanban-box">
<div>
<field name="color" widget="selection"/>
</div>
</t>
</templates>
</kanban>`,
});
const ev = new PointerEvent("pointerdown", { bubbles: true, cancelable: true });
const select = target.querySelector(".o_kanban_record .o_field_widget[name=color] select");
select.dispatchEvent(ev);
assert.notOk(ev.defaultPrevented);
});
});