[FIX] web: scroll to selected tab in settings page

Before this commit, in the settings page on mobile mode, when swiping
between the different apps, on the app selector the current app stay
selected on the right corner. The selected app will stay on top of the
other apps, and the app selector itself didn't move.

Now, when swiping between the different apps, the app selector moves to
force the current app to be in the center of the selector.

closes odoo/odoo#141524

Task-id: 3489756
X-original-commit: d35bddfc2cab706d19d33c3335bbae54acd27fbf
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Signed-off-by: Jorge Pinna Puissant (jpp) <jpp@odoo.com>
This commit is contained in:
Jorge Pinna Puissant
2023-11-08 08:54:11 +00:00
parent 1220b3e6f8
commit 174301ef0f
3 changed files with 22 additions and 7 deletions
@@ -4,6 +4,7 @@ import { localization } from "@web/core/l10n/localization";
import { clamp } from "@web/core/utils/numbers";
import { Component, onMounted, onWillUnmount, useRef, useState } from "@odoo/owl";
import { Deferred } from "@web/core/utils/concurrency";
const isScrollSwipable = (scrollables) => {
return {
@@ -164,21 +165,23 @@ export class ActionSwiper extends Component {
if (this.props.animationType === "bounce") {
this.state.containerStyle = `transform: translateX(${this.swipedDistance}px)`;
this.actionTimeoutId = browser.setTimeout(() => {
action();
action(Promise.resolve());
this._reset();
}, 500);
} else if (this.props.animationType === "forwards") {
this.state.containerStyle = `transform: translateX(${this.swipedDistance}px)`;
this.actionTimeoutId = browser.setTimeout(() => {
action();
const prom = new Deferred();
action(prom);
this.state.isSwiping = true;
this.state.containerStyle = `transform: translateX(${-this.swipedDistance}px)`;
this.resetTimeoutId = browser.setTimeout(() => {
prom.resolve();
this._reset();
}, 100);
}, 100);
} else {
return action();
return action(Promise.resolve());
}
}
}
@@ -15,6 +15,7 @@ export class SettingsPage extends Component {
}
this.settingsRef = useRef("settings");
this.settingsTabRef = useRef("settings_tab");
this.scrollMap = Object.create(null);
useEffect(
(settingsEl, currentTab) => {
@@ -47,11 +48,22 @@ export class SettingsPage extends Component {
this.getCurrentIndex() !== this.props.modules.length - 1
);
}
onRightSwipe() {
async onRightSwipe(prom) {
this.state.selectedTab = this.props.modules[this.getCurrentIndex() - 1].key;
await prom;
this.scrollToSelectedTab();
}
onLeftSwipe() {
async onLeftSwipe(prom) {
this.state.selectedTab = this.props.modules[this.getCurrentIndex() + 1].key;
await prom;
this.scrollToSelectedTab();
}
scrollToSelectedTab() {
const key = this.state.selectedTab;
this.settingsTabRef.el
.querySelector(`[data-key='${key}']`)
.scrollIntoView({ behavior: "smooth", inline: "center", block: "nearest" });
}
onSettingTabClick(key) {
@@ -3,11 +3,11 @@
<t t-name="web.SettingsPage">
<div class="o_setting_container">
<div class="position-sticky top-0 flex-grow-0 z-index-1">
<div class="settings_tab h-100 border-end" t-if="!env.isSmall or state.search.value.length === 0">
<div class="settings_tab h-100 border-end" t-if="!env.isSmall or state.search.value.length === 0" t-ref="settings_tab">
<t t-foreach="props.modules" t-as="module" t-key="module.key">
<div class="tab" t-if="!module.isVisible"
t-att-class="{
'selected': state.selectedTab === module.key and state.search.value.length === 0, 'position-sticky start-0 end-0 text-bg-primary z-index-1 shadow-none': state.selectedTab === module.key and state.search.value.length === 0 and env.isSmall
'selected': state.selectedTab === module.key and state.search.value.length === 0, 'text-bg-primary shadow-none': state.selectedTab === module.key and state.search.value.length === 0 and env.isSmall
}" t-att-data-key="module.key" role="tab" t-on-click="() => this.onSettingTabClick(module.key)">
<div class="icon d-none d-md-block" t-attf-style="background : url('{{module.imgurl}}') no-repeat center;background-size:contain;"/> <span class="app_name"><t t-esc="module.string"/></span>
</div>