[FIX] kanban: click outside of a quick create record

When on click outside of a quick create record, one wants
    - to remove the quick create record if it is not dirty
    - not to remove it if it is dirty with some exceptions:
        if the click is on a "Create", "Load more" or "+" (quick add) button

This fix makes the external listener of KanbanRecordQuickCreate work as
expected.

Part-of: odoo/odoo#92475
This commit is contained in:
Mathieu Duckerts-Antoine
2022-06-30 09:29:47 +02:00
committed by Aaron Bohy
parent dcbf2119fc
commit be8472c851
2 changed files with 195 additions and 3 deletions
@@ -5,6 +5,12 @@ import { FormRenderer } from "@web/views/form/form_renderer";
const { Component, onMounted, useExternalListener, useState, useRef } = owl;
const ACTION_SELECTORS = [
".o_kanban_quick_add",
".o_kanban_load_more button",
".o-kanban-button-new",
];
export class KanbanRecordQuickCreate extends Component {
setup() {
this.uiService = useService("ui");
@@ -28,9 +34,17 @@ export class KanbanRecordQuickCreate extends Component {
return;
}
const target = this.mousedownTarget || ev.target;
const gotClickedInside = this.rootRef.el.contains(target);
if (!gotClickedInside) {
this.cancel(false);
const gotClickedOutside = !this.rootRef.el.contains(target);
if (gotClickedOutside) {
let force = false;
for (const selector of ACTION_SELECTORS) {
const closestEl = target.closest(selector);
if (closestEl) {
force = true;
break;
}
}
this.cancel(force);
}
this.mousedownTarget = null;
},
@@ -9619,4 +9619,182 @@ QUnit.module("Views", (hooks) => {
assert.containsOnce(target, ".o_kanban_group:nth-child(2) .o_kanban_record");
assert.verifySteps(["get_views", "web_read_group", "web_search_read", "web_search_read"]);
});
QUnit.test("quick create record and click outside (no dirty input)", async (assert) => {
await makeView({
type: "kanban",
resModel: "partner",
serverData,
arch: `
<kanban limit="2">
<field name="bar"/>
<templates>
<t t-name="kanban-box">
<div>
<field name="foo"/>
</div>
</t>
</templates>
</kanban>`,
groupBy: ["bar"],
createRecord: () => {
assert.step("create record");
},
});
assert.containsNone(target, ".o_kanban_quick_create");
await quickCreateRecord();
assert.containsOnce(target, ".o_kanban_quick_create");
assert.containsOnce(target, ".o_kanban_group:nth-child(1) .o_kanban_quick_create");
await click(target, ".o_control_panel");
assert.containsNone(target, ".o_kanban_quick_create");
await quickCreateRecord();
assert.containsOnce(target, ".o_kanban_quick_create");
assert.containsOnce(target, ".o_kanban_group:nth-child(1) .o_kanban_quick_create");
await quickCreateRecord(1);
assert.containsOnce(target, ".o_kanban_quick_create");
assert.containsOnce(target, ".o_kanban_group:nth-child(2) .o_kanban_quick_create");
await click(target, ".o_kanban_load_more button");
assert.containsNone(target, ".o_kanban_quick_create");
await quickCreateRecord();
assert.containsOnce(target, ".o_kanban_quick_create");
assert.containsOnce(target, ".o_kanban_group:nth-child(1) .o_kanban_quick_create");
assert.verifySteps([]);
await click(target, ".o-kanban-button-new");
assert.verifySteps(["create record"]);
assert.containsNone(target, ".o_kanban_quick_create");
});
QUnit.test("quick create record and click outside (with dirty input)", async (assert) => {
await makeView({
type: "kanban",
resModel: "partner",
serverData,
arch: `
<kanban limit="2">
<field name="bar"/>
<templates>
<t t-name="kanban-box">
<div>
<field name="foo"/>
</div>
</t>
</templates>
</kanban>`,
groupBy: ["bar"],
createRecord: () => {
assert.step("create record");
},
});
assert.containsNone(target, ".o_kanban_quick_create");
await quickCreateRecord();
assert.containsOnce(target, ".o_kanban_quick_create");
assert.containsOnce(target, ".o_kanban_group:nth-child(1) .o_kanban_quick_create");
await editInput(target, ".o_kanban_quick_create [name=display_name] input", "ABC");
assert.strictEqual(
target.querySelector(".o_kanban_quick_create [name=display_name] input").value,
"ABC"
);
await click(target, ".o_control_panel");
assert.containsOnce(target, ".o_kanban_quick_create");
assert.containsOnce(target, ".o_kanban_group:nth-child(1) .o_kanban_quick_create");
assert.strictEqual(
target.querySelector(".o_kanban_quick_create [name=display_name] input").value,
"ABC"
);
await quickCreateRecord(1);
assert.containsOnce(target, ".o_kanban_quick_create");
assert.containsOnce(target, ".o_kanban_group:nth-child(2) .o_kanban_quick_create");
assert.strictEqual(
target.querySelector(".o_kanban_quick_create [name=display_name] input").value,
""
);
await editInput(target, ".o_kanban_quick_create [name=display_name] input", "ABC");
assert.strictEqual(
target.querySelector(".o_kanban_quick_create [name=display_name] input").value,
"ABC"
);
await click(target, ".o_kanban_load_more button");
assert.containsNone(target, ".o_kanban_quick_create");
await quickCreateRecord();
assert.containsOnce(target, ".o_kanban_quick_create");
assert.containsOnce(target, ".o_kanban_group:nth-child(1) .o_kanban_quick_create");
await editInput(target, ".o_kanban_quick_create [name=display_name] input", "ABC");
assert.strictEqual(
target.querySelector(".o_kanban_quick_create [name=display_name] input").value,
"ABC"
);
assert.verifySteps([]);
await click(target, ".o-kanban-button-new");
assert.verifySteps(["create record"]);
assert.containsNone(target, ".o_kanban_quick_create");
});
QUnit.test("quick create record and click on 'Load more'", async (assert) => {
await makeView({
type: "kanban",
resModel: "partner",
serverData,
arch: `
<kanban limit="2">
<field name="bar"/>
<templates>
<t t-name="kanban-box">
<div>
<field name="foo"/>
</div>
</t>
</templates>
</kanban>`,
groupBy: ["bar"],
});
assert.containsNone(target, ".o_kanban_quick_create");
await quickCreateRecord(1);
assert.containsOnce(target, ".o_kanban_quick_create");
assert.containsOnce(target, ".o_kanban_group:nth-child(2) .o_kanban_quick_create");
assert.containsN(target, ".o_kanban_group:nth-child(2) .o_kanban_record", 2);
await click(target, ".o_kanban_load_more button");
await nextTick();
assert.containsNone(target, ".o_kanban_quick_create");
assert.containsN(target, ".o_kanban_group:nth-child(2) .o_kanban_record", 3);
});
});