fix(shopfloor): mobile scroll works — remove nested scroll containers
User: "scrolling is not working" in Chrome DevTools mobile simulation.
Three actual problems:
1. Plant Overview columns had max-height: calc(100vh - 180px) +
overflow: hidden, with a nested overflow-y: auto on the column
body. Classic Trello kanban pattern — works on desktop, breaks
on mobile. You get two scroll containers fighting each other and
the PAGE itself can't scroll past the viewport height.
2. .o_fp_po_columns had overflow-x: auto on all widths. On the
phone-stack breakpoint (<600px) this was also still on, creating
another nested scroll container.
3. Draggable cards can swallow touch events on mobile because
touch-action defaults to "auto" and Chrome's mobile simulator
treats touch on draggable elements as potential drag-start.
Fixes — all at the <=900px breakpoint (tablets + phones):
.o_fp_po_column max-height: none; overflow: visible
.o_fp_po_col_body overflow-y: visible
.o_fp_po_columns flex-direction: column; overflow: visible
Plus .o_fp_po_card carries `touch-action: pan-y` unconditionally —
touch-scroll gestures never get hijacked by the draggable="true"
attribute. Desktop mousedown drag still works (HTML5 drag-drop
isn't touch-based by default).
Also added -webkit-overflow-scrolling: touch to all three page
roots (.o_fp_tablet, .o_fp_manager, .o_fp_plant_overview) and to
the internal scroll containers that remain on desktop — gives iOS
Safari proper momentum scroll (11 occurrences in the compiled
bundle).
Drag-drop JS preventDefault calls audited — they only fire on
dragover/drop (HTML5 drag events), which don't exist on touch by
default, so no touch interference there.
Verified via compiled CSS:
.o_fp_po_card { touch-action: pan-y; ... }
@media (max-width: 900px) .o_fp_po_column { overflow-x: visible;
overflow-y: visible; min-height: auto }
@media (max-width: 900px) .o_fp_po_col_body { overflow-y: visible }
Version bumped 19.0.5.0.0 -> 19.0.6.0.0 to force the bundle hash
to change. New URL: /web/assets/4a1b69e/web.assets_backend.min.css
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
'name': 'Fusion Plating — Shop Floor',
|
'name': 'Fusion Plating — Shop Floor',
|
||||||
'version': '19.0.5.0.0',
|
'version': '19.0.6.0.0',
|
||||||
'category': 'Manufacturing/Plating',
|
'category': 'Manufacturing/Plating',
|
||||||
'summary': 'Shop-floor tablet stations, QR scanning, bake window enforcer, '
|
'summary': 'Shop-floor tablet stations, QR scanning, bake window enforcer, '
|
||||||
'first-piece inspection gates.',
|
'first-piece inspection gates.',
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: $fp-space-6;
|
gap: $fp-space-6;
|
||||||
|
// Smooth momentum scroll on iOS / iPadOS Safari
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
|
||||||
@media (max-width: 900px) { padding: $fp-space-4; gap: $fp-space-4; }
|
@media (max-width: 900px) { padding: $fp-space-4; gap: $fp-space-4; }
|
||||||
@media (max-width: 600px) { padding: $fp-space-3; gap: $fp-space-4; }
|
@media (max-width: 600px) { padding: $fp-space-3; gap: $fp-space-4; }
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: $fp-space-6;
|
gap: $fp-space-6;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
|
||||||
@media (max-width: 900px) { padding: $fp-space-4; gap: $fp-space-4; }
|
@media (max-width: 900px) { padding: $fp-space-4; gap: $fp-space-4; }
|
||||||
@media (max-width: 600px) { padding: $fp-space-3; gap: $fp-space-4; }
|
@media (max-width: 600px) { padding: $fp-space-3; gap: $fp-space-4; }
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -112,13 +113,21 @@
|
|||||||
gap: $fp-space-4;
|
gap: $fp-space-4;
|
||||||
padding: 0 $fp-space-6 $fp-space-6;
|
padding: 0 $fp-space-6 $fp-space-6;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
||||||
@media (max-width: 900px) { padding: 0 $fp-space-4 $fp-space-4; }
|
// Mobile: stack vertically, remove the horizontal overflow (and
|
||||||
@media (max-width: 600px) {
|
// therefore the inner scroll trap); the page scrolls instead.
|
||||||
|
@media (max-width: 900px) {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
overflow-x: visible;
|
||||||
|
overflow-y: visible;
|
||||||
|
min-height: auto;
|
||||||
|
padding: 0 $fp-space-4 $fp-space-4;
|
||||||
|
}
|
||||||
|
@media (max-width: 600px) {
|
||||||
padding: 0 $fp-space-3 $fp-space-3;
|
padding: 0 $fp-space-3 $fp-space-3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,10 +147,15 @@
|
|||||||
max-height: calc(100vh - 180px);
|
max-height: calc(100vh - 180px);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
// Touch / mobile: let columns be their natural height and let the
|
||||||
|
// PAGE scroll instead of each column having its own internal
|
||||||
|
// scroll. Nested scroll containers are unusable on a phone.
|
||||||
|
@media (max-width: 900px) {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
min-width: 100%; max-width: 100%;
|
min-width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
max-height: none;
|
max-height: none;
|
||||||
|
overflow: visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,9 +187,18 @@
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: $fp-space-3;
|
padding: $fp-space-3;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
// Smooth inertial scroll on iOS Safari
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
transition: background-color $fp-dur $fp-ease,
|
transition: background-color $fp-dur $fp-ease,
|
||||||
box-shadow $fp-dur $fp-ease;
|
box-shadow $fp-dur $fp-ease;
|
||||||
|
|
||||||
|
// Mobile: disable the nested overflow so the page scrolls the
|
||||||
|
// whole list naturally instead of trapping scroll inside each
|
||||||
|
// column.
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
overflow-y: visible;
|
||||||
|
}
|
||||||
|
|
||||||
// Drop-zone highlight: soft accent tint + inset outline. Shows the
|
// Drop-zone highlight: soft accent tint + inset outline. Shows the
|
||||||
// whole column is receptive. The actual insertion point is drawn
|
// whole column is receptive. The actual insertion point is drawn
|
||||||
// by the real placeholder node (inserted by JS) between cards.
|
// by the real placeholder node (inserted by JS) between cards.
|
||||||
@@ -220,6 +243,10 @@
|
|||||||
margin-bottom: $fp-space-2;
|
margin-bottom: $fp-space-2;
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
box-shadow: $fp-elev-1;
|
box-shadow: $fp-elev-1;
|
||||||
|
// Allow vertical page-scroll gestures on touch — without this
|
||||||
|
// a draggable card can swallow the touch and block scrolling.
|
||||||
|
// Desktop drag (mousedown) still works.
|
||||||
|
touch-action: pan-y;
|
||||||
transition: transform $fp-dur-fast $fp-ease,
|
transition: transform $fp-dur-fast $fp-ease,
|
||||||
box-shadow $fp-dur $fp-ease,
|
box-shadow $fp-dur $fp-ease,
|
||||||
opacity $fp-dur $fp-ease,
|
opacity $fp-dur $fp-ease,
|
||||||
|
|||||||
Reference in New Issue
Block a user