diff --git a/web_responsive/README.rst b/web_responsive/README.rst index eaa28661d66d..034fdb9fdf8a 100644 --- a/web_responsive/README.rst +++ b/web_responsive/README.rst @@ -61,13 +61,9 @@ This module adds responsiveness to web backend. **Features for mobile**: \* View type picker dropdown displays comfortably -- Control panel buttons use icons to save space. - - |image6| - - Followers and send button is displayed on mobile. Avatar is hidden. - |image7| + |image6| - Big inputs on form in edit mode @@ -79,23 +75,23 @@ comfortably be more intuitive or accessible by fingers of one hand. F.x. Alt + S for Save - |image8| + |image7| - Autofocus on search menu box when opening the app menu - |image9| + |image8| - When the chatter is on the side part, the document viewer fills that part for side-by-side reading instead of full screen. You can still put it on full width preview clicking on the new maximize button. - |image10| + |image9| - When the user chooses to send a public message the color of the composer is different from the one when the message is an internal log. - |image11| + |image10| .. |image| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/redirecthome.gif .. |image1| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/appmenu.gif @@ -103,12 +99,11 @@ comfortably .. |image3| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/listview.gif .. |image4| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/formview.gif .. |image5| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/listview.gif -.. |image6| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/form_buttons.gif -.. |image7| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/chatter.png -.. |image8| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/shortcuts.gif -.. |image9| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/appsearch.gif -.. |image10| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/document_viewer.gif -.. |image11| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/chatter-colors.png +.. |image6| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/chatter.png +.. |image7| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/shortcuts.gif +.. |image8| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/appsearch.gif +.. |image9| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/document_viewer.gif +.. |image10| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_responsive/static/img/chatter-colors.png **Table of contents** @@ -179,6 +174,14 @@ Contributors - Angel Patel +- Chau Le + +Other credits +------------- + +The migration of this module from 17.0 to 18.0 was financially supported +by Camptocamp. + Maintainers ----------- diff --git a/web_responsive/__manifest__.py b/web_responsive/__manifest__.py index 2c772995ab8d..373ffbcc1ddf 100644 --- a/web_responsive/__manifest__.py +++ b/web_responsive/__manifest__.py @@ -9,7 +9,7 @@ { "name": "Web Responsive", "summary": "Responsive web client, community-supported", - "version": "17.0.1.1.3", + "version": "18.0.1.0.0", "category": "Website", "website": "https://github.com/OCA/web", "author": "LasLabs, Tecnativa, ITerra, Onestein, " @@ -50,9 +50,6 @@ "/web_responsive/static/src/components/command_palette/*", "/web_responsive/static/src/views/form/*", ], - "web.assets_tests": [ - "/web_responsive/static/tests/test_patch.js", - ], "web.qunit_suite_tests": [ "/web_responsive/static/tests/apps_menu_tests.esm.js", "/web_responsive/static/tests/apps_menu_search_tests.esm.js", diff --git a/web_responsive/readme/CONTRIBUTORS.md b/web_responsive/readme/CONTRIBUTORS.md index 8e7d7d5e2c25..faaaf57ecfad 100644 --- a/web_responsive/readme/CONTRIBUTORS.md +++ b/web_responsive/readme/CONTRIBUTORS.md @@ -21,3 +21,5 @@ - Taras Shabaranskyi \<\> - Angel Patel \<\> + +- Chau Le \<\> diff --git a/web_responsive/readme/CREDITS.md b/web_responsive/readme/CREDITS.md new file mode 100644 index 000000000000..83b3ec91f7d5 --- /dev/null +++ b/web_responsive/readme/CREDITS.md @@ -0,0 +1 @@ +The migration of this module from 17.0 to 18.0 was financially supported by Camptocamp. diff --git a/web_responsive/readme/DESCRIPTION.md b/web_responsive/readme/DESCRIPTION.md index 9e2714aad6a8..a6eb682fbb0f 100644 --- a/web_responsive/readme/DESCRIPTION.md +++ b/web_responsive/readme/DESCRIPTION.md @@ -32,10 +32,6 @@ their profile settings. **Features for mobile**: \* View type picker dropdown displays comfortably -- Control panel buttons use icons to save space. - - ![image](../static/img/form_buttons.gif) - - Followers and send button is displayed on mobile. Avatar is hidden. ![image](../static/img/chatter.png) diff --git a/web_responsive/static/description/index.html b/web_responsive/static/description/index.html index 668be0abad30..cfe128dd6064 100644 --- a/web_responsive/static/description/index.html +++ b/web_responsive/static/description/index.html @@ -397,11 +397,8 @@

Web Responsive

Features for mobile: * View type picker dropdown displays comfortably

    -
  • Control panel buttons use icons to save space.

    -

    image6

    -
  • Followers and send button is displayed on mobile. Avatar is hidden.

    -

    image7

    +

    image6

  • Big inputs on form in edit mode

  • @@ -413,20 +410,20 @@

    Web Responsive

    with Firefox Tab switching. Standard Odoo keyboard hotkeys changed to be more intuitive or accessible by fingers of one hand. F.x. Alt + S for Save

    -

    image8

    +

    image7

  • Autofocus on search menu box when opening the app menu

    -

    image9

    +

    image8

  • When the chatter is on the side part, the document viewer fills that part for side-by-side reading instead of full screen. You can still put it on full width preview clicking on the new maximize button.

    -

    image10

    +

    image9

  • When the user chooses to send a public message the color of the composer is different from the one when the message is an internal log.

    -

    image11

    +

    image10

Table of contents

@@ -438,7 +435,8 @@

Web Responsive

  • Credits
  • @@ -496,10 +494,16 @@

    Contributors

  • David Vidal <david.vidal@tecnativa.com>
  • Taras Shabaranskyi <shabaranskij@gmail.com>
  • Angel Patel <patelangel1414@gmail.com>
  • +
  • Chau Le <chaulb@trobz.com>
  • +
    +

    Other credits

    +

    The migration of this module from 17.0 to 18.0 was financially supported +by Camptocamp.

    +
    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association diff --git a/web_responsive/static/img/form_buttons.gif b/web_responsive/static/img/form_buttons.gif deleted file mode 100644 index 93f9897220fb..000000000000 Binary files a/web_responsive/static/img/form_buttons.gif and /dev/null differ diff --git a/web_responsive/static/src/components/apps_menu/apps_menu.esm.js b/web_responsive/static/src/components/apps_menu/apps_menu.esm.js index b1c3b2f29b25..15d6e2c14b07 100644 --- a/web_responsive/static/src/components/apps_menu/apps_menu.esm.js +++ b/web_responsive/static/src/components/apps_menu/apps_menu.esm.js @@ -1,4 +1,3 @@ -/** @odoo-module **/ /* Copyright 2018 Tecnativa - Jairo Llopis * Copyright 2021 ITerra - Sergey Shebanin * Copyright 2023 Onestein - Anjeel Haria @@ -6,38 +5,44 @@ * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ import {Component, onWillStart, useState} from "@odoo/owl"; -import {session} from "@web/session"; import {useBus, useService} from "@web/core/utils/hooks"; import {AppMenuItem} from "@web_responsive/components/apps_menu_item/apps_menu_item.esm"; import {AppsMenuSearchBar} from "@web_responsive/components/menu_searchbar/searchbar.esm"; import {NavBar} from "@web/webclient/navbar/navbar"; import {WebClient} from "@web/webclient/webclient"; +import {browser} from "@web/core/browser/browser"; import {patch} from "@web/core/utils/patch"; +import {router} from "@web/core/browser/router"; +import {session} from "@web/session"; import {useHotkey} from "@web/core/hotkeys/hotkey_hook"; -import {browser} from "@web/core/browser/browser"; +import {user} from "@web/core/user"; + +/* global document */ +/* global location */ +/* global window */ // Patch WebClient to show AppsMenu instead of default app patch(WebClient.prototype, { setup() { super.setup(); + useBus(this.env.bus, "APPS_MENU:STATE_CHANGED", ({detail: state}) => { document.body.classList.toggle("o_apps_menu_opened", state); }); - this.user = useService("user"); onWillStart(async () => { const is_redirect_home = await this.orm.searchRead( "res.users", - [["id", "=", this.user.userId]], + [["id", "=", user.userId]], ["is_redirect_home"] ); - this.env.services.user.updateContext({ + user.updateContext({ is_redirect_to_home: is_redirect_home[0]?.is_redirect_home, }); }); this.redirect = false; }, _loadDefaultApp() { - if (this.env.services.user.context.is_redirect_to_home) { + if (user.context.is_redirect_to_home) { this.env.bus.trigger("APPS_MENU:STATE_CHANGED", true); } else { super._loadDefaultApp(); @@ -52,9 +57,9 @@ export class AppsMenu extends Component { this.theme = session.apps_menu.theme || "milk"; this.menuService = useService("menu"); browser.localStorage.setItem("redirect_menuId", ""); - if (this.env.services.user.context.is_redirect_to_home) { - this.router = useService("router"); - const menuId = Number(this.router.current.hash.menu_id || 0); + + if (user.context.is_redirect_to_home) { + const menuId = Number(router.current.menu_id || 0); this.state = useState({open: menuId === 0}); } useBus(this.env.bus, "ACTION_MANAGER:UI-UPDATED", () => { @@ -75,98 +80,75 @@ export class AppsMenu extends Component { const repeatable = { allowRepeat: true, }; - useHotkey( - "ArrowRight", - () => { - this._onWindowKeydown("next"); - }, - repeatable - ); - useHotkey( - "ArrowLeft", - () => { - this._onWindowKeydown("prev"); - }, - repeatable - ); - useHotkey( - "ArrowDown", - () => { - this._onWindowKeydown("next"); - }, - repeatable - ); - useHotkey( - "ArrowUp", - () => { - this._onWindowKeydown("prev"); - }, - repeatable - ); + + const keyActions = [ + {key: "ArrowRight", action: "next"}, + {key: "ArrowLeft", action: "prev"}, + {key: "ArrowDown", action: "next"}, + {key: "ArrowUp", action: "prev"}, + ]; + + keyActions.forEach(({key, action}) => { + useHotkey( + key, + () => { + this._onWindowKeydown(action); + }, + repeatable + ); + }); + useHotkey("Escape", () => { this.env.bus.trigger("ACTION_MANAGER:UI-UPDATED"); }); } _onWindowKeydown(direction) { - const focusableInputElements = document.querySelectorAll(".o-app-menu-item"); + const focusableInputElements = Array.from( + document.querySelectorAll(".o-app-menu-item") + ); + const currentIndex = focusableInputElements.indexOf(document.activeElement); + if (focusableInputElements.length) { - const focusable = [...focusableInputElements]; - const index = focusable.indexOf(document.activeElement); - let nextIndex = 0; - if (direction === "prev" && index >= 0) { - if (index > 0) { - nextIndex = index - 1; - } else { - nextIndex = focusable.length - 1; - } - } else if (direction === "next") { - if (index + 1 < focusable.length) { - nextIndex = index + 1; - } else { - nextIndex = 0; - } + const lastIndex = focusableInputElements.length - 1; + + let nextIndex = null; + if (direction === "next") { + nextIndex = currentIndex < lastIndex ? currentIndex + 1 : 0; + } else if (direction === "prev") { + nextIndex = currentIndex > 0 ? currentIndex - 1 : lastIndex; } - focusableInputElements[nextIndex].focus(); + + focusableInputElements[nextIndex]?.focus(); } } onMenuClick() { - if (!this.env.services.user.context.is_redirect_to_home) { - this.setOpenState(!this.state.open); - } else { - const redirect_menuId = - browser.localStorage.getItem("redirect_menuId") || ""; - if (!redirect_menuId) { - this.setOpenState(true); - } else { - this.setOpenState(!this.state.open); - } - const {href, hash} = location; - const menuId = this.router.current.hash.menu_id; - if (menuId && menuId != redirect_menuId) { - console.log(this.router.current.hash.menu_id); - browser.localStorage.setItem( - "redirect_menuId", - this.router.current.hash.menu_id - ); + const isRedirect = user.context.is_redirect_to_home; + const redirectMenuId = browser.localStorage.getItem("redirect_menuId") || ""; + const {href, hash} = location; + + if (isRedirect) { + const shouldOpenState = !redirectMenuId || !this.state.open; + this.setOpenState(shouldOpenState); + + const currentMenuId = router.current.menu_id; + if (currentMenuId && currentMenuId !== redirectMenuId) { + browser.localStorage.setItem("redirect_menuId", currentMenuId); } if (href.includes(hash)) { window.history.replaceState(null, "", href.replace(hash, "")); } + } else { + this.setOpenState(!this.state.open); } } } -Object.assign(AppsMenu, { - template: "web_responsive.AppsMenu", - props: { - slots: { - type: Object, - optional: true, - }, - }, -}); +AppsMenu.template = "web_responsive.AppsMenu"; +AppsMenu.props = { + slots: {type: Object, optional: true}, +}; Object.assign(NavBar.components, {AppsMenu, AppMenuItem, AppsMenuSearchBar}); diff --git a/web_responsive/static/src/components/apps_menu/apps_menu.scss b/web_responsive/static/src/components/apps_menu/apps_menu.scss index 6ddfe5790ea2..cd88edddcfb2 100644 --- a/web_responsive/static/src/components/apps_menu/apps_menu.scss +++ b/web_responsive/static/src/components/apps_menu/apps_menu.scss @@ -44,7 +44,7 @@ } // hide and save odoo default QUnit tests -.o_navbar_apps_menu.hide .dropdown-toggle { +.o_navbar_apps_menu.hide { position: absolute !important; z-index: -100 !important; } diff --git a/web_responsive/static/src/components/apps_menu/apps_menu.xml b/web_responsive/static/src/components/apps_menu/apps_menu.xml index 7e0a877f5786..836fd8a45e29 100644 --- a/web_responsive/static/src/components/apps_menu/apps_menu.xml +++ b/web_responsive/static/src/components/apps_menu/apps_menu.xml @@ -6,10 +6,9 @@ License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). --> - - 'o_navbar_apps_menu hide' - true - + + o_navbar_apps_menu hide + shift+h @@ -23,7 +22,7 @@ app="app" currentApp="currentApp" href="getMenuItemHref(app)" - onClick="onNavBarDropdownItemSelection.bind(this)" + onClick.bind="onNavBarDropdownItemSelection" /> diff --git a/web_responsive/static/src/components/apps_menu/apps_menu_preferences.esm.js b/web_responsive/static/src/components/apps_menu/apps_menu_preferences.esm.js index 9f6678ff4cad..0237f65fd577 100644 --- a/web_responsive/static/src/components/apps_menu/apps_menu_preferences.esm.js +++ b/web_responsive/static/src/components/apps_menu/apps_menu_preferences.esm.js @@ -1,15 +1,14 @@ -/** @odoo-module **/ /* Copyright 2023 Taras Shabaranskyi * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ import {Component, xml} from "@odoo/owl"; import {registry} from "@web/core/registry"; import {useService} from "@web/core/utils/hooks"; +import {user} from "@web/core/user"; class AppsMenuPreferences extends Component { setup() { this.action = useService("action"); - this.user = useService("user"); } async _onClick() { @@ -17,7 +16,7 @@ class AppsMenuPreferences extends Component { const action = await this.action.loadAction( "web_responsive.res_users_view_form_apps_menu_preferences_action" ); - this.action.doAction({...action, res_id: this.user.userId}, {onClose}).then(); + this.action.doAction({...action, res_id: user.userId}, {onClose}); } } diff --git a/web_responsive/static/src/components/apps_menu_item/apps_menu_item.esm.js b/web_responsive/static/src/components/apps_menu_item/apps_menu_item.esm.js index 70b271240d3e..5cad7420595e 100644 --- a/web_responsive/static/src/components/apps_menu_item/apps_menu_item.esm.js +++ b/web_responsive/static/src/components/apps_menu_item/apps_menu_item.esm.js @@ -1,4 +1,3 @@ -/** @odoo-module **/ /* Copyright 2018 Tecnativa - Jairo Llopis * Copyright 2021 ITerra - Sergey Shebanin * Copyright 2023 Onestein - Anjeel Haria @@ -16,16 +15,11 @@ export class AppMenuItem extends Component { } get isActive() { - const {currentApp} = this.props; - return currentApp && currentApp.id === this.props.app.id; + return this.props.currentApp?.id === this.props.app.id; } get className() { - const classItems = ["o-app-menu-item"]; - if (this.isActive) { - classItems.push("active"); - } - return classItems.join(" "); + return ["o-app-menu-item", this.isActive && "active"].filter(Boolean).join(" "); } onUpdateProps(nextProps) { @@ -33,21 +27,17 @@ export class AppMenuItem extends Component { } onClick() { - if (typeof this.props.onClick === "function") { - this.props.onClick(this.props.app); - } + this.props.onClick?.(this.props.app); } } -Object.assign(AppMenuItem, { - template: "web_responsive.AppMenuItem", - props: { - app: Object, - href: String, - currentApp: { - type: Object, - optional: true, - }, - onClick: Function, +AppMenuItem.template = "web_responsive.AppMenuItem"; +AppMenuItem.props = { + app: Object, + href: String, + currentApp: { + type: Object, + optional: true, }, -}); + onClick: Function, +}; diff --git a/web_responsive/static/src/components/apps_menu_tools.esm.js b/web_responsive/static/src/components/apps_menu_tools.esm.js index 4626d67a69bf..ad7e592732ba 100644 --- a/web_responsive/static/src/components/apps_menu_tools.esm.js +++ b/web_responsive/static/src/components/apps_menu_tools.esm.js @@ -1,5 +1,3 @@ -/** @odoo-module **/ - /* Copyright 2018 Tecnativa - Jairo Llopis * Copyright 2021 ITerra - Sergey Shebanin * Copyright 2023 Onestein - Anjeel Haria diff --git a/web_responsive/static/src/components/chatter/chatter.esm.js b/web_responsive/static/src/components/chatter/chatter.esm.js index b12fc7ae0a48..a5c21bf46fad 100644 --- a/web_responsive/static/src/components/chatter/chatter.esm.js +++ b/web_responsive/static/src/components/chatter/chatter.esm.js @@ -1,10 +1,9 @@ -/** @odoo-module **/ /* Copyright 2021 ITerra - Sergey Shebanin * Copyright 2023 Onestein - Anjeel Haria * Copyright 2023 Taras Shabaranskyi * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ -import {Chatter} from "@mail/core/web/chatter"; +import {Chatter} from "@mail/chatter/web_portal/chatter"; import {patch} from "@web/core/utils/patch"; import {useEffect} from "@odoo/owl"; diff --git a/web_responsive/static/src/components/chatter/chatter.xml b/web_responsive/static/src/components/chatter/chatter.xml index 6890045726f7..e9cd51d3f837 100644 --- a/web_responsive/static/src/components/chatter/chatter.xml +++ b/web_responsive/static/src/components/chatter/chatter.xml @@ -10,10 +10,7 @@ '' - + @@ -22,7 +19,6 @@ position="replace" >