[FIX] web,*: fix kanban useSortable screen width limit
Reproduce: Go on a kanban view, with enough columns so it goes off the screens. Scroll on the right, try to drag anything beyond the original (before scrolling) limit of the screen. The cards are stuck floating at that limit. Note it didn't prevent the drop to work properly where the mouse was. Issue: The useSortable hook gets an owl ref, which is used as a limit to where things can be dragged and dropped. Originaly and logically, it was the current component ref, the renderer. But for some unknown reason, this space was not getting wider than the initial screen size. It may be a problem with the flexbox layout. Tried solutions: - A first solution was to add the overflow-x-scroll css property to the renderer. It works, but now the horizontal scroll bar is no longer always visible. You have to scroll all the way down to see it. UX wise this is not acceptable. - We could remove the clamp mecanism inside useSortable to let the drag and drop motion go anywhere. This works, but decrease the quality of the interaction. It looks cheap and not polished. Final Solution Finally, we decided to pass a ref to the o_content div from the layout component down to the kanban renderer. If the useSortable is given this ref, it works as intended. While it may seem too much, it is not unreasonable to propose a reference to the most parent element of the view contents to the renderer. X-original-commit: a569305acaa1c812ede739c267e2e9530945f65f Part-of: odoo/odoo#102756
This commit is contained in:
committed by
Julien Mougenot
parent
81defa2804
commit
2e8d9cdf18
+1
-1
@@ -2,7 +2,7 @@
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="project.ProjectUpdateKanbanView" t-inherit="web.KanbanView" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//Layout" position="inside">
|
||||
<xpath expr="//t[@t-set-slot='default']" position="inside">
|
||||
<ProjectRightSidePanel
|
||||
context="props.context"
|
||||
domain="props.domain"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { pick } from "@web/core/utils/objects";
|
||||
|
||||
const { Component } = owl;
|
||||
const { Component, useRef } = owl;
|
||||
|
||||
/**
|
||||
* @param {Object} params
|
||||
@@ -15,6 +15,7 @@ export function extractLayoutComponents(params) {
|
||||
export class Layout extends Component {
|
||||
setup() {
|
||||
this.components = extractLayoutComponents(this.env.config);
|
||||
this.contentRef = useRef("content");
|
||||
}
|
||||
get controlPanelSlots() {
|
||||
const slots = { ...this.props.slots };
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
</t>
|
||||
<t t-component="components.ControlPanel" slots="controlPanelSlots" t-if="display.controlPanel" display="display.controlPanel"/>
|
||||
<t t-component="components.Banner" t-if="display.banner"/>
|
||||
<div class="o_content" t-attf-class="{{props.className}}" t-att-class="{ o_component_with_search_panel: display.searchPanel }">
|
||||
<div t-ref="content" class="o_content" t-attf-class="{{props.className}}" t-att-class="{ o_component_with_search_panel: display.searchPanel }">
|
||||
<t t-component="components.SearchPanel" t-if="display.searchPanel"/>
|
||||
<t t-slot="default"/>
|
||||
<t t-slot="default" contentRef="contentRef" />
|
||||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
@@ -7,14 +7,18 @@
|
||||
<t t-set-slot="layout-buttons">
|
||||
<t t-call="{{ props.buttonTemplate }}"/>
|
||||
</t>
|
||||
<t t-component="props.Renderer"
|
||||
list="model.root"
|
||||
archInfo="props.archInfo"
|
||||
readonly="true"
|
||||
forceGlobalClick="props.forceGlobalClick"
|
||||
openRecord.bind="openRecord"
|
||||
noContentHelp="props.info.noContentHelp"
|
||||
/>
|
||||
<t t-set-slot="default" t-slot-scope="scope">
|
||||
<t t-component="props.Renderer"
|
||||
list="model.root"
|
||||
archInfo="props.archInfo"
|
||||
readonly="true"
|
||||
forceGlobalClick="props.forceGlobalClick"
|
||||
openRecord.bind="openRecord"
|
||||
noContentHelp="props.info.noContentHelp"
|
||||
layoutContentRef="scope.contentRef"
|
||||
/>
|
||||
</t>
|
||||
|
||||
</Layout>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -49,7 +49,7 @@ export class KanbanRenderer extends Component {
|
||||
useSortable({
|
||||
enable: () => this.canResequenceRecords,
|
||||
// Params
|
||||
ref: rootRef,
|
||||
ref: this.props.layoutContentRef || rootRef,
|
||||
elements: ".o_record_draggable",
|
||||
ignore: ".dropdown",
|
||||
groups: () => this.props.list.isGrouped && ".o_kanban_group",
|
||||
@@ -610,6 +610,7 @@ KanbanRenderer.props = [
|
||||
"readonly",
|
||||
"forceGlobalClick?",
|
||||
"noContentHelp?",
|
||||
"layoutContentRef?",
|
||||
];
|
||||
KanbanRenderer.components = {
|
||||
Dropdown,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<xpath expr="//t[@t-component='props.Renderer']" position="attributes">
|
||||
<attribute name="activeWebsite">state.activeWebsite</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//Layout" position="inside">
|
||||
<xpath expr="//t[@t-set-slot='default']" position="inside">
|
||||
<t t-set-slot="control-panel-website-extra-actions">
|
||||
<t t-call="website.RecordFilter"/>
|
||||
</t>
|
||||
|
||||
Reference in New Issue
Block a user