From 097c7bc91df4af2a5741795c55e0227c0630d7a4 Mon Sep 17 00:00:00 2001 From: Khushi Date: Tue, 13 Feb 2024 13:09:47 +0000 Subject: [PATCH] [FIX] documents: handle multiple clicks on record in selectCreateDialog Steps to reproduce: - Go to Documents activity view. - Click on Schedule activity. - Perform multiple clicks on any record. Issue: The 'Schedule Activity' wizard opened as many times as the record was clicked. As a result, even after successfully scheduling an activity on that record, the user still faced multiple open wizards remaining and had to manually close each one of them. Fix: This commit introduces a method `executeOnceAndClose` which makes use of a flag 'busy' to ensure that the `onSelected` function is called only once and hence exactly one `Schedule Activity` wizard is opened, despite clicking a record more than once. closes odoo/odoo#154442 Task: 3721404 X-original-commit: 19cc5ea3cf2c8fcf742ba5ab9b4b82305d81d555 Signed-off-by: Aaron Bohy (aab) --- .../view_dialogs/select_create_dialog.js | 20 ++++++++++++++---- .../select_create_dialog_tests.js | 21 +++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/addons/web/static/src/views/view_dialogs/select_create_dialog.js b/addons/web/static/src/views/view_dialogs/select_create_dialog.js index 011750d2575..776dcdad2e3 100644 --- a/addons/web/static/src/views/view_dialogs/select_create_dialog.js +++ b/addons/web/static/src/views/view_dialogs/select_create_dialog.js @@ -19,6 +19,7 @@ export class SelectCreateDialog extends Component { // ℹ️ `_t` can only be inlined directly inside JS template literals // after Babel has been updated to version 2.12. const translatedText = _t("No records found!"); + this.busy = false; // flag used to ensure we only call once the onSelected/onUnselect props this.baseViewProps = { display: { searchPanel: false }, editable: false, // readonly @@ -52,17 +53,28 @@ export class SelectCreateDialog extends Component { return props; } + async executeOnceAndClose(callback) { + if (!this.busy) { + this.busy = true; + try { + await callback(); + } catch (e) { + this.busy = false; + throw e; + } + this.props.close(); + } + } + async select(resIds) { if (this.props.onSelected) { - await this.props.onSelected(resIds); - this.props.close(); + this.executeOnceAndClose(() => this.props.onSelected(resIds)); } } async unselect() { if (this.props.onUnselect) { - await this.props.onUnselect(); - this.props.close(); + this.executeOnceAndClose(() => this.props.onUnselect()); } } diff --git a/addons/web/static/tests/views/view_dialogs/select_create_dialog_tests.js b/addons/web/static/tests/views/view_dialogs/select_create_dialog_tests.js index 7939bbfa02a..902318cec6c 100644 --- a/addons/web/static/tests/views/view_dialogs/select_create_dialog_tests.js +++ b/addons/web/static/tests/views/view_dialogs/select_create_dialog_tests.js @@ -480,6 +480,27 @@ QUnit.module("ViewDialogs", (hooks) => { } ); + QUnit.test("SelectCreateDialog: multiple clicks on record", async function (assert) { + serverData.views = { + "partner,false,list": ``, + "partner,false,search": ``, + }; + const webClient = await createWebClient({ serverData }); + webClient.env.services.dialog.add(SelectCreateDialog, { + resModel: "partner", + onSelected: async function (records) { + assert.step(`select record ${records[0]}`); + }, + }); + + await nextTick(); + click(target.querySelector(".modal .o_data_row .o_data_cell")); + click(target.querySelector(".modal .o_data_row .o_data_cell")); + click(target.querySelector(".modal .o_data_row .o_data_cell")); + await nextTick(); + assert.verifySteps(["select record 1"], "should have called onSelected only once"); + }); + QUnit.test("SelectCreateDialog: default props, create a record", async function (assert) { serverData.views = { "partner,false,list": ``,