[IMP] web_editor: improve the handling of overlapping dropzones

In [1], jQueryUI drag and drop was removed and replace by an in-house
solution.

This version introduced a difficulty when dragging and dropping content
when the dropzones are overlapping. This commit tries to mitigate that
by always choosing the dropzone that is the closest to the helper
element displayed when dragging.

[1]: https://github.com/odoo/odoo/commit/7594d71ca8610d5947e80f325ccb57abc23c2c76

task-3577109

closes odoo/odoo#143167

Signed-off-by: Guillaume Dieleman (gdi) <gdi@odoo.com>
This commit is contained in:
Arthur Detroux (ard)
2023-12-05 19:53:24 +00:00
parent b1b3d22dfe
commit b08a47afde
@@ -3,7 +3,7 @@ import { makeDraggableHook } from "@web/core/utils/draggable_hook_builder";
import { pick } from "@web/core/utils/objects";
import { reactive } from "@odoo/owl";
import { throttleForAnimation } from "@web/core/utils/timing";
import { touching } from "@web/core/utils/ui";
import { closest, touching } from "@web/core/utils/ui";
/** @typedef {import("@web/core/utils/draggable_hook_builder").DraggableHandlerParams} DraggableHandlerParams */
/** @typedef {import("@web/core/utils/draggable_hook_builder").DraggableBuilderParams} DraggableBuilderParams */
@@ -150,7 +150,7 @@ const dragAndDropHookParams = {
width: helperRect.width,
height: helperRect.height,
};
const dropzoneEl = touching(ctx.getDropZones(), helperRect)[0];
const dropzoneEl = closest(touching(ctx.getDropZones(), helperRect), helperRect);
// Update the drop zone if it's in grid mode
if (ctx.current.dropzone?.el && ctx.current.dropzone.el.classList.contains("oe_grid_zone")) {
ctx.current.dropzone.rect = ctx.current.dropzone.el.getBoundingClientRect();
@@ -158,8 +158,11 @@ const dragAndDropHookParams = {
if (
ctx.current.dropzone &&
(
ctx.current.dropzone.el === dropzoneEl ||
touching([ctx.current.helper], ctx.current.dropzone.rect).length > 0
ctx.current.dropzone.el === dropzoneEl
|| (
!dropzoneEl
&& touching([ctx.current.helper], ctx.current.dropzone.rect).length > 0
)
)
) {
// If no new dropzone but old one is still valid, return early.