[FIX] web,project: Restore kanban drag&drop in Firefox
Before this commit, the drag & drop feature for the Project "Tasks" kanban view did not work if the drag sequence was initiated from the title of the card. This was due to the "o_kanban_record_headings" class having the CSS rule `overflow: hidden`, because of a well known 6 year-long-and-counting bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1352061 Namely: mouse enter|leave events won't fire on anything underneath elements having `overflow: hidden`. This commit solves this issue by introducing a dedicated class name 'o_dragged' to all elements dragged using the `draggable_hook_builder`, and defining on it the CSS attributes that were assigned in JS before, as well as `pointer-events: none` on itself and all its children to avoid the issue mentioned above. Also in this commit: fixed a syntax error in a CSS rule in project's "task_name_with_subtask_count_char_field" widget. closes odoo/odoo#105353 Related: odoo/enterprise#33774 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
+1
-1
@@ -6,7 +6,7 @@
|
||||
<span
|
||||
class="text-muted ms-2"
|
||||
t-out="formattedSubtaskCount"
|
||||
style="{ font-weight: normal; }"
|
||||
style="font-weight: normal;"
|
||||
/>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
@@ -81,6 +81,7 @@ const DEFAULT_DEFAULT_PARAMS = {
|
||||
threshold: 30,
|
||||
},
|
||||
};
|
||||
const DRAGGED_CLASS = "o_dragged";
|
||||
const LEFT_CLICK = 0;
|
||||
const MANDATORY_PARAMS = ["ref", "elements"];
|
||||
|
||||
@@ -247,9 +248,6 @@ export function makeDraggableHook(hookParams = {}) {
|
||||
ctx.offset.y -= eRect.y;
|
||||
|
||||
addStyle(ctx.currentElement, {
|
||||
position: "fixed",
|
||||
"pointer-events": "none",
|
||||
"z-index": 1000,
|
||||
width: `${eRect.width}px`,
|
||||
height: `${eRect.height}px`,
|
||||
left: `${eRect.x}px`,
|
||||
@@ -271,6 +269,9 @@ export function makeDraggableHook(hookParams = {}) {
|
||||
cleanups.push(cleanupFn);
|
||||
}
|
||||
|
||||
ctx.currentElement.classList.add(DRAGGED_CLASS);
|
||||
cleanups.push(() => ctx.currentElement.classList.remove(DRAGGED_CLASS));
|
||||
|
||||
execBuildHandler("onDragStart");
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
.o_dragged {
|
||||
position: fixed !important;
|
||||
z-index: 1000 !important;
|
||||
|
||||
// In FireFox: elements with `overflow: hidden` will prevent mouseenter and mouseleave
|
||||
// events from firing on elements underneath them. This is the case when dragging a card
|
||||
// by the `.o_kanban_record_headings` element. In such cases, the pointer events are
|
||||
// disabled to allow mouse events to fire properly.
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1352061
|
||||
&,
|
||||
* {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
@@ -139,8 +139,7 @@ export const useSortable = makeDraggableHook({
|
||||
|
||||
const { width, height } = ctx.currentElementRect;
|
||||
|
||||
// Prepares the ghost element
|
||||
ctx.ghostElement = ctx.currentElement.cloneNode(false);
|
||||
// Ghost element is hidden and its size is frozen
|
||||
ctx.ghostElement.style = `visibility: hidden; display: block; width: ${width}px; height:${height}px;`;
|
||||
|
||||
// Binds handlers on eligible groups, if the elements are not confined to
|
||||
@@ -193,6 +192,7 @@ export const useSortable = makeDraggableHook({
|
||||
ctx.currentContainer = ctx.currentGroup;
|
||||
}
|
||||
}
|
||||
ctx.ghostElement = ctx.currentElement.cloneNode(false);
|
||||
},
|
||||
onCleanup({ ctx }) {
|
||||
if (ctx.ghostElement) {
|
||||
|
||||
@@ -530,7 +530,7 @@ export class KanbanRenderer extends Component {
|
||||
* @param {HTMLElement} [params.group]
|
||||
*/
|
||||
sortStart({ element }) {
|
||||
element.classList.add("o_dragged", "shadow");
|
||||
element.classList.add("shadow");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -539,7 +539,7 @@ export class KanbanRenderer extends Component {
|
||||
* @param {HTMLElement} [params.group]
|
||||
*/
|
||||
sortStop({ element, group }) {
|
||||
element.classList.remove("o_dragged", "shadow");
|
||||
element.classList.remove("shadow");
|
||||
if (group) {
|
||||
group.classList.remove("o_kanban_hover");
|
||||
}
|
||||
|
||||
@@ -1745,18 +1745,14 @@ export class ListRenderer extends Component {
|
||||
* @param {HTMLElement} params.element
|
||||
* @param {HTMLElement} [params.group]
|
||||
*/
|
||||
sortStart({ element }) {
|
||||
element.classList.add("o_dragged");
|
||||
}
|
||||
sortStart() {}
|
||||
|
||||
/**
|
||||
* @param {Object} params
|
||||
* @param {HTMLElement} params.element
|
||||
* @param {HTMLElement} [params.group]
|
||||
*/
|
||||
sortStop({ element }) {
|
||||
element.classList.remove("o_dragged");
|
||||
}
|
||||
sortStop() {}
|
||||
}
|
||||
|
||||
ListRenderer.template = "web.ListRenderer";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { dragAndDrop, getFixture, mount, nextTick } from "@web/../tests/helpers/utils";
|
||||
import { drag, dragAndDrop, getFixture, mount, nextTick } from "@web/../tests/helpers/utils";
|
||||
import { useSortable } from "@web/core/utils/sortable";
|
||||
|
||||
import { Component, reactive, useRef, useState, xml } from "@odoo/owl";
|
||||
@@ -88,7 +88,7 @@ QUnit.module("UI", ({ beforeEach }) => {
|
||||
});
|
||||
|
||||
QUnit.test("Simple sorting in single group", async (assert) => {
|
||||
assert.expect(19);
|
||||
assert.expect(22);
|
||||
|
||||
class List extends Component {
|
||||
setup() {
|
||||
@@ -132,12 +132,18 @@ QUnit.module("UI", ({ beforeEach }) => {
|
||||
await mount(List, target);
|
||||
|
||||
assert.containsN(target, ".item", 3);
|
||||
assert.containsNone(target, ".o_dragged");
|
||||
assert.verifySteps([]);
|
||||
|
||||
// First item after 2nd item
|
||||
await dragAndDrop(".item:first-child", ".item:nth-child(2)");
|
||||
const drop = await drag(".item:first-child", ".item:nth-child(2)");
|
||||
|
||||
assert.hasClass(target.querySelector(".item"), "o_dragged");
|
||||
|
||||
await drop();
|
||||
|
||||
assert.containsN(target, ".item", 3);
|
||||
assert.containsNone(target, ".o_dragged");
|
||||
assert.verifySteps(["start", "elemententer", "stop", "drop"]);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user