[IMP] web: use customized closing function in dialog

This commit allows a child component of a dialog to change the behaviour
when you want to close that dialog.

To change the behaviour of a dialog, the component must overwrite
env.dialogData.close.

closes odoo/odoo#120520

Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
This commit is contained in:
FrancoisGe
2023-05-08 19:21:44 +02:00
parent 2656ad936f
commit dc1191f693
4 changed files with 34 additions and 7 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ export class Dialog extends Component {
this.data.close();
});
this.id = `dialog_${this.data.id}`;
useChildSubEnv({ inDialog: true, dialogId: this.id, closeDialog: this.data.close });
useChildSubEnv({ inDialog: true, dialogId: this.id, closeDialog: () => this.data.close() });
this.position = useState({ left: 0, top: 0 });
useDialogDraggable({
ref: this.modalRef,
+4 -4
View File
@@ -13,7 +13,7 @@
<header t-if="props.header" class="modal-header">
<t t-slot="header" close="data.close" isFullscreen="isFullscreen">
<t t-call="web.Dialog.header">
<t t-set="close" t-value="data.close"/>
<t t-set="close" t-value="() => this.data.close()"/>
<t t-set="fullscreen" t-value="isFullscreen"/>
</t>
</t>
@@ -21,14 +21,14 @@
<!-- FIXME: WOWL there is a bug on t-portal on owl, in which t-portal don't work on multinode.
To avoid this we place the footer before the body -->
<footer t-if="props.footer" class="modal-footer justify-content-around justify-content-sm-start flex-wrap gap-1" style="order:2">
<t t-slot="footer" close="data.close">
<button class="btn btn-primary o-default-button" t-on-click="data.close">
<t t-slot="footer" close="() => this.data.close()">
<button class="btn btn-primary o-default-button" t-on-click="() => this.data.close()">
<t>Ok</t>
</button>
</t>
</footer>
<main class="modal-body" t-attf-class="{{ props.bodyClass }} {{ !props.withBodyPadding ? 'p-0': '' }}">
<t t-slot="default" close="data.close" />
<t t-slot="default" close="() => this.data.close()" />
</main>
</div>
</div>
@@ -17,7 +17,7 @@
</xpath>
<xpath expr="//t[@t-slot='header']" position="replace">
<t t-call="web.ActionDialog.header">
<t t-set="close" t-value="props.close"/>
<t t-set="close" t-value="() => this.data.close()"/>
<t t-set="fullscreen" t-value="props.isFullscreen"/>
</t>
</xpath>
@@ -27,7 +27,7 @@
<xpath expr="//t[@t-slot='footer']" position="replace">
<t t-if="!isLegacy">
<t t-slot="buttons">
<button class="btn btn-primary o-default-button" t-on-click="data.close">Ok</button>
<button class="btn btn-primary o-default-button" t-on-click="() => this.data.close()">Ok</button>
</t>
</t>
</xpath>
@@ -116,6 +116,33 @@ QUnit.module("Components", (hooks) => {
assert.verifySteps(["close"]);
});
QUnit.test(
"click on the button x triggers the close defined by a Child component",
async function (assert) {
assert.expect(3);
const env = await makeDialogTestEnv();
class Child extends Component {
static template = xml`<div>Hello</div>`;
setup() {
this.env.dialogData.close = () => assert.step("close");
}
}
class Parent extends Component {}
Parent.template = xml`
<Dialog>
<Child/>
</Dialog>
`;
Parent.components = { Child, Dialog };
parent = await mount(Parent, target, { env });
assert.containsOnce(target, ".o_dialog");
await click(target, ".o_dialog header button.btn-close");
assert.verifySteps(["close"]);
}
);
QUnit.test(
"click on the default footer button triggers the service close",
async function (assert) {