From 13fc4751a4f66bf12adbfd5c057688c8287bb6c0 Mon Sep 17 00:00:00 2001 From: "Michael (mcm)" Date: Wed, 1 Feb 2023 15:30:01 +0000 Subject: [PATCH] [IMP] web: allow to move dialog After this commit, the user will be able to move dialogs to see the content hidden behind the dialog. closes odoo/odoo#111654 Task: 3132894 Signed-off-by: Aaron Bohy (aab) --- addons/web/static/src/core/dialog/dialog.js | 52 ++++++++++++++++++- addons/web/static/src/core/dialog/dialog.xml | 2 +- .../src/core/utils/draggable_hook_builder.js | 2 +- addons/web/static/tests/core/dialog_tests.js | 52 ++++++++++++++++++- 4 files changed, 103 insertions(+), 5 deletions(-) diff --git a/addons/web/static/src/core/dialog/dialog.js b/addons/web/static/src/core/dialog/dialog.js index b661438c49d..5da7dbd4b3b 100644 --- a/addons/web/static/src/core/dialog/dialog.js +++ b/addons/web/static/src/core/dialog/dialog.js @@ -3,8 +3,34 @@ import { useHotkey } from "@web/core/hotkeys/hotkey_hook"; import { useActiveElement } from "../ui/ui_service"; import { useForwardRefToParent } from "@web/core/utils/hooks"; +import { Component, useChildSubEnv, useExternalListener, useState } from "@odoo/owl"; +import { throttleForAnimation } from "@web/core/utils/timing"; +import { makeDraggableHook } from "../utils/draggable_hook_builder"; + +const useDialogDraggable = makeDraggableHook({ + name: "useDialogDraggable", + onWillStartDrag({ ctx, addCleanup, addStyle, getRect }) { + const { height, width } = getRect(ctx.current.element); + ctx.current.container = document.createElement("div"); + addStyle(ctx.current.container, { + position: "fixed", + top: "0", + bottom: `${70 - height}px`, + left: `${70 - width}px`, + right: `${70 - width}px`, + }); + ctx.current.element.after(ctx.current.container); + addCleanup(() => ctx.current.container.remove()); + }, + onDrop({ ctx, getRect }) { + const { top, left } = getRect(ctx.current.element); + return { + left: left - ctx.current.elementRect.left, + top: top - ctx.current.elementRect.top, + }; + }, +}); -import { Component, useChildSubEnv, useState } from "@odoo/owl"; export class Dialog extends Component { setup() { this.modalRef = useForwardRefToParent("modalRef"); @@ -15,7 +41,20 @@ export class Dialog extends Component { }); this.id = `dialog_${this.data.id}`; useChildSubEnv({ inDialog: true, dialogId: this.id, closeDialog: this.data.close }); - + this.position = useState({ left: 0, top: 0 }); + useDialogDraggable({ + ref: this.modalRef, + elements: ".modal-content", + handle: ".modal-header", + ignore: "button", + edgeScrolling: { enabled: false }, + onDrop: ({ top, left }) => { + this.position.left += left; + this.position.top += top; + }, + }); + const throttledResize = throttleForAnimation(this.onResize.bind(this)); + useExternalListener(window, "resize", throttledResize); owl.onWillDestroy(() => { if (this.env.isSmall) { this.data.scrollToOrigin(); @@ -26,6 +65,15 @@ export class Dialog extends Component { get isFullscreen() { return this.props.fullscreen || this.env.isSmall; } + + get contentStyle() { + return `top: ${this.position.top}px; left: ${this.position.left}px;`; + } + + onResize() { + this.position.left = 0; + this.position.top = 0; + } } Dialog.template = "web.Dialog"; Dialog.props = { diff --git a/addons/web/static/src/core/dialog/dialog.xml b/addons/web/static/src/core/dialog/dialog.xml index 4936e28f92c..12f6b05c5df 100644 --- a/addons/web/static/src/core/dialog/dialog.xml +++ b/addons/web/static/src/core/dialog/dialog.xml @@ -9,7 +9,7 @@ t-ref="modalRef" >