diff --git a/setup/web_responsive/odoo/addons/web_responsive b/setup/web_responsive/odoo/addons/web_responsive new file mode 120000 index 000000000..a084a42d2 --- /dev/null +++ b/setup/web_responsive/odoo/addons/web_responsive @@ -0,0 +1 @@ +../../../../web_responsive \ No newline at end of file diff --git a/setup/web_responsive/setup.py b/setup/web_responsive/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/web_responsive/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/web_responsive/README.rst b/web_responsive/README.rst index 0de22a80f..b0a52c29b 100644 --- a/web_responsive/README.rst +++ b/web_responsive/README.rst @@ -14,16 +14,16 @@ Web Responsive :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github - :target: https://github.com/OCA/web/tree/14.0/web_responsive + :target: https://github.com/OCA/web/tree/15.0/web_responsive :alt: OCA/web .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/web-14-0/web-14-0-web_responsive :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/162/14.0 + :target: https://runbot.odoo-community.org/runbot/162/15.0 :alt: Try me on Runbot -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| This module adds responsiveness to web backend. @@ -152,7 +152,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -196,11 +196,14 @@ promote its widespread use. .. |maintainer-Tardo| image:: https://github.com/Tardo.png?size=40px :target: https://github.com/Tardo :alt: Tardo +.. |maintainer-SplashS| image:: https://github.com/SplashS.png?size=40px + :target: https://github.com/SplashS + :alt: SplashS Current `maintainers `__: -|maintainer-Yajo| |maintainer-Tardo| +|maintainer-Yajo| |maintainer-Tardo| |maintainer-SplashS| -This module is part of the `OCA/web `_ project on GitHub. +This module is part of the `OCA/web `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/web_responsive/__manifest__.py b/web_responsive/__manifest__.py index 46117ddf7..e23ee1f55 100644 --- a/web_responsive/__manifest__.py +++ b/web_responsive/__manifest__.py @@ -1,30 +1,49 @@ # Copyright 2016-2017 LasLabs Inc. # Copyright 2017-2018 Tecnativa - Jairo Llopis # Copyright 2018-2019 Tecnativa - Alexandre Díaz +# Copyright 2021 ITerra - Sergey Shebanin # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). { "name": "Web Responsive", "summary": "Responsive web client, community-supported", - "version": "14.0.1.0.2", + "version": "15.0.1.0.0", "category": "Website", "website": "https://github.com/OCA/web", - "author": "LasLabs, Tecnativa, " "Odoo Community Association (OCA)", + "author": "LasLabs, Tecnativa, ITerra, " "Odoo Community Association (OCA)", "license": "LGPL-3", "installable": True, "depends": ["web", "mail"], "development_status": "Production/Stable", - "maintainers": ["Yajo", "Tardo"], - "data": ["views/assets.xml", "views/res_users.xml", "views/web.xml"], - "qweb": [ - "static/src/xml/apps.xml", - "static/src/xml/form_buttons.xml", - "static/src/xml/menu.xml", - "static/src/xml/navbar.xml", - "static/src/xml/attachment_viewer.xml", - "static/src/xml/discuss.xml", - "static/src/xml/control_panel.xml", - "static/src/xml/search_panel.xml", - ], + "maintainers": ["Yajo", "Tardo", "SplashS"], + "data": ["views/res_users.xml", "views/web.xml"], + "assets": { + "web.assets_backend": [ + "/web_responsive/static/src/legacy/css/web_responsive.scss", + "/web_responsive/static/src/legacy/js/web_responsive.js", + "/web_responsive/static/src/legacy/css/kanban_view_mobile.scss", + "/web_responsive/static/src/legacy/js/kanban_renderer_mobile.js", + "/web_responsive/static/src/components/ui_context.esm.js", + "/web_responsive/static/src/components/apps_menu/apps_menu.scss", + "/web_responsive/static/src/components/apps_menu/apps_menu.esm.js", + "/web_responsive/static/src/components/navbar/main_navbar.scss", + "/web_responsive/static/src/components/control_panel/control_panel.scss", + "/web_responsive/static/src/components/control_panel/control_panel.esm.js", + "/web_responsive/static/src/components/search_panel/search_panel.scss", + "/web_responsive/static/src/components/search_panel/search_panel.esm.js", + "/web_responsive/static/src/components/attachment_viewer/attachment_viewer.scss", + "/web_responsive/static/src/components/attachment_viewer/attachment_viewer.esm.js", + "/web_responsive/static/src/components/hotkey/hotkey.scss", + ], + "web.assets_qweb": [ + "/web_responsive/static/src/legacy/xml/form_buttons.xml", + "/web_responsive/static/src/components/apps_menu/apps_menu.xml", + "/web_responsive/static/src/components/control_panel/control_panel.xml", + "/web_responsive/static/src/components/navbar/main_navbar.xml", + "/web_responsive/static/src/components/search_panel/search_panel.xml", + "/web_responsive/static/src/components/attachment_viewer/attachment_viewer.xml", + "/web_responsive/static/src/components/hotkey/hotkey.xml", + ], + }, "sequence": 1, } diff --git a/web_responsive/i18n/fa.po b/web_responsive/i18n/fa.po deleted file mode 100644 index ff6d14784..000000000 --- a/web_responsive/i18n/fa.po +++ /dev/null @@ -1,179 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_responsive -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" -"Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2021-09-23 07:34+0000\n" -"Last-Translator: Saeed Raeisi \n" -"Language-Team: none\n" -"Language: fa\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.3.2\n" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/search_panel.xml:0 -#, python-format -msgid "All" -msgstr "همه" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/control_panel.xml:0 -#, python-format -msgid "CLEAR" -msgstr "پاک کردن" - -#. module: web_responsive -#: model:ir.model.fields,field_description:web_responsive.field_res_users__chatter_position -msgid "Chatter Position" -msgstr "موقعیت چت باکس" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#, python-format -msgid "Create" -msgstr "ایجاد" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#, python-format -msgid "Discard" -msgstr "لغو" - -#. module: web_responsive -#: model:ir.model.fields,field_description:web_responsive.field_res_users__display_name -msgid "Display Name" -msgstr "نام نمایشی" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#, python-format -msgid "Edit" -msgstr "ویرایش" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/control_panel.xml:0 -#: code:addons/web_responsive/static/src/xml/search_panel.xml:0 -#, python-format -msgid "FILTER" -msgstr "فیلتر" - -#. module: web_responsive -#: model:ir.model.fields,field_description:web_responsive.field_res_users__id -msgid "ID" -msgstr "شناسه" - -#. module: web_responsive -#: model:ir.model.fields,field_description:web_responsive.field_res_users____last_update -msgid "Last Modified on" -msgstr "آخرین ویرایش در" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/attachment_viewer.xml:0 -#: code:addons/web_responsive/static/src/xml/attachment_viewer.xml:0 -#, python-format -msgid "Maximize" -msgstr "بزرگ کردن" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/attachment_viewer.xml:0 -#: code:addons/web_responsive/static/src/xml/attachment_viewer.xml:0 -#, python-format -msgid "Minimize" -msgstr "کوچک کردن" - -#. module: web_responsive -#: model:ir.model.fields.selection,name:web_responsive.selection__res_users__chatter_position__normal -msgid "Normal" -msgstr "عادی" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#, python-format -msgid "Quick actions" -msgstr "اقدامات سریع" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/control_panel.xml:0 -#: code:addons/web_responsive/static/src/xml/search_panel.xml:0 -#, python-format -msgid "SEE RESULT" -msgstr "مشاهده نتیجه" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#, python-format -msgid "Save" -msgstr "ذخیره" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/apps.xml:0 -#, python-format -msgid "Search menus..." -msgstr "جستجو در منو..." - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/control_panel.xml:0 -#: code:addons/web_responsive/static/src/xml/control_panel.xml:0 -#, python-format -msgid "Search..." -msgstr "جستجو..." - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/menu.xml:0 -#, python-format -msgid "Shift" -msgstr "شیفت" - -#. module: web_responsive -#: model:ir.model.fields.selection,name:web_responsive.selection__res_users__chatter_position__sided -msgid "Sided" -msgstr "طرف" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#, python-format -msgid "Today" -msgstr "امروز" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/js/kanban_renderer_mobile.js:0 -#, python-format -msgid "Undefined" -msgstr "تعریف نشده" - -#. module: web_responsive -#: model:ir.model,name:web_responsive.model_res_users -msgid "Users" -msgstr "کاربران" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/control_panel.xml:0 -#, python-format -msgid "View switcher" -msgstr "تعویض کننده نما" diff --git a/web_responsive/i18n/fa_IR.po b/web_responsive/i18n/fa_IR.po deleted file mode 100644 index 500bec743..000000000 --- a/web_responsive/i18n/fa_IR.po +++ /dev/null @@ -1,177 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_responsive -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" -"Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: fa_IR\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: nplurals=2; plural=n > 1;\n" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/search_panel.xml:0 -#, python-format -msgid "All" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/control_panel.xml:0 -#, python-format -msgid "CLEAR" -msgstr "" - -#. module: web_responsive -#: model:ir.model.fields,field_description:web_responsive.field_res_users__chatter_position -msgid "Chatter Position" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#, python-format -msgid "Create" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#, python-format -msgid "Discard" -msgstr "" - -#. module: web_responsive -#: model:ir.model.fields,field_description:web_responsive.field_res_users__display_name -msgid "Display Name" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#, python-format -msgid "Edit" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/control_panel.xml:0 -#: code:addons/web_responsive/static/src/xml/search_panel.xml:0 -#, python-format -msgid "FILTER" -msgstr "" - -#. module: web_responsive -#: model:ir.model.fields,field_description:web_responsive.field_res_users__id -msgid "ID" -msgstr "" - -#. module: web_responsive -#: model:ir.model.fields,field_description:web_responsive.field_res_users____last_update -msgid "Last Modified on" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/attachment_viewer.xml:0 -#: code:addons/web_responsive/static/src/xml/attachment_viewer.xml:0 -#, python-format -msgid "Maximize" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/attachment_viewer.xml:0 -#: code:addons/web_responsive/static/src/xml/attachment_viewer.xml:0 -#, python-format -msgid "Minimize" -msgstr "" - -#. module: web_responsive -#: model:ir.model.fields.selection,name:web_responsive.selection__res_users__chatter_position__normal -msgid "Normal" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#, python-format -msgid "Quick actions" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/control_panel.xml:0 -#: code:addons/web_responsive/static/src/xml/search_panel.xml:0 -#, python-format -msgid "SEE RESULT" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#, python-format -msgid "Save" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/apps.xml:0 -#, python-format -msgid "Search menus..." -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/control_panel.xml:0 -#: code:addons/web_responsive/static/src/xml/control_panel.xml:0 -#, python-format -msgid "Search..." -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/menu.xml:0 -#, python-format -msgid "Shift" -msgstr "" - -#. module: web_responsive -#: model:ir.model.fields.selection,name:web_responsive.selection__res_users__chatter_position__sided -msgid "Sided" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/form_buttons.xml:0 -#, python-format -msgid "Today" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/js/kanban_renderer_mobile.js:0 -#, python-format -msgid "Undefined" -msgstr "" - -#. module: web_responsive -#: model:ir.model,name:web_responsive.model_res_users -msgid "Users" -msgstr "" - -#. module: web_responsive -#. openerp-web -#: code:addons/web_responsive/static/src/xml/control_panel.xml:0 -#, python-format -msgid "View switcher" -msgstr "" diff --git a/web_responsive/i18n/fr.po b/web_responsive/i18n/fr.po index 13d6d5ce8..ff04b8c3c 100644 --- a/web_responsive/i18n/fr.po +++ b/web_responsive/i18n/fr.po @@ -6,15 +6,15 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2021-09-25 08:34+0000\n" -"Last-Translator: Rémi \n" +"PO-Revision-Date: 2020-07-22 12:19+0000\n" +"Last-Translator: c2cdidier \n" "Language-Team: none\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.3.2\n" +"X-Generator: Weblate 3.10\n" #. module: web_responsive #. openerp-web @@ -54,7 +54,7 @@ msgstr "Annuler" #: code:addons/web_responsive/static/src/xml/form_view.xml:0 #, python-format msgid "Edit" -msgstr "Modifier" +msgstr "Editer" #. module: web_responsive #. openerp-web @@ -99,9 +99,9 @@ msgstr "Rechercher dans les menus..." #. module: web_responsive #. openerp-web #: code:addons/web_responsive/static/src/xml/menu.xml:0 -#, fuzzy, python-format +#, python-format msgid "Shift" -msgstr "Shift" +msgstr "" #. module: web_responsive #: model:ir.model.fields.selection,name:web_responsive.selection__res_users__chatter_position__sided @@ -120,19 +120,18 @@ msgstr "Utilisateurs" msgid "" "btn btn-secondary o_mail_discuss_button_multi_user_channel d-md-block d-none" msgstr "" -"btn btn-secondary o_mail_discuss_button_multi_user_channel d-md-block d-none" #. module: web_responsive #. openerp-web #: code:addons/web_responsive/static/src/xml/apps.xml:0 #: code:addons/web_responsive/static/src/xml/document_viewer.xml:0 -#, fuzzy, python-format +#, python-format msgid "false" -msgstr "false" +msgstr "" #. module: web_responsive #. openerp-web #: code:addons/web_responsive/static/src/xml/document_viewer.xml:0 #, python-format msgid "modal o_modal_fullscreen o_document_viewer o_responsive_document_viewer" -msgstr "modal o_modal_fullscreen o_document_viewer o_responsive_document_viewer" +msgstr "" diff --git a/web_responsive/models/res_users.py b/web_responsive/models/res_users.py index 5247df678..ef1fc947c 100644 --- a/web_responsive/models/res_users.py +++ b/web_responsive/models/res_users.py @@ -9,19 +9,18 @@ class ResUsers(models.Model): chatter_position = fields.Selection( [("normal", "Normal"), ("sided", "Sided")], - string="Chatter Position", default="sided", ) - def __init__(self, pool, cr): - """Override of __init__ to add access rights. - Access rights are disabled by default, but allowed on some specific - fields defined in self.SELF_{READ/WRITE}ABLE_FIELDS. - """ - super().__init__(pool, cr) - # duplicate list to avoid modifying the original reference - type(self).SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS) - type(self).SELF_WRITEABLE_FIELDS.extend(["chatter_position"]) - # duplicate list to avoid modifying the original reference - type(self).SELF_READABLE_FIELDS = list(self.SELF_READABLE_FIELDS) - type(self).SELF_READABLE_FIELDS.extend(["chatter_position"]) + """Override to add access rights. + Access rights are disabled by default, but allowed on some specific + fields defined in self.SELF_{READ/WRITE}ABLE_FIELDS. + """ + + @property + def SELF_READABLE_FIELDS(self): + return super().SELF_READABLE_FIELDS + ["chatter_position"] + + @property + def SELF_WRITEABLE_FIELDS(self): + return super().SELF_WRITEABLE_FIELDS + ["chatter_position"] diff --git a/web_responsive/readme/DESCRIPTION.rst b/web_responsive/readme/DESCRIPTION.rst index 87a1b3dc8..903e30efc 100644 --- a/web_responsive/readme/DESCRIPTION.rst +++ b/web_responsive/readme/DESCRIPTION.rst @@ -1,28 +1,40 @@ This module adds responsiveness to web backend. -Features for all devices: +**Features for all devices**: -* New navigation with an app drawer +* New navigation with the fullscreen app menu - .. image:: https://user-images.githubusercontent.com/973709/48417193-09a1e080-e74a-11e8-8a0c-e73eb689b2fb.gif + .. image:: ../static/img/appmenu.gif -* Quick menu search from the app drawer +* Quick menu search inside the app menu .. image:: https://user-images.githubusercontent.com/973709/48417213-17576600-e74a-11e8-846a-57691e82636b.gif -Features for mobile: +* Sticky header & footer in list view + + .. image:: ../static/img/listview.gif + +* Sticky statusbar in form view + + .. image:: ../static/img/formview.gif + +* Bigger checkboxes in list view + + .. image:: ../static/img/big_checkboxes.gif + +**Features for mobile**: * App-specific submenus are shown on full screen when toggling them from the "hamburger" menu .. image:: https://user-images.githubusercontent.com/973709/48417297-51286c80-e74a-11e8-9a47-22c810b18c43.gif -* View type picker dropdown displays confortably +* View type picker dropdown displays comfortably .. image:: https://user-images.githubusercontent.com/973709/50964322-e3d55580-14c6-11e9-8249-48db9539600f.gif * Top app bar is always visible, but the control panel is hidden when - scrolling down, to save some vaulable vertical space + scrolling down, to save some valuable vertical space .. image:: https://user-images.githubusercontent.com/973709/50964496-5cd4ad00-14c7-11e9-9261-fd223a329d02.gif @@ -35,20 +47,38 @@ Features for mobile: .. image:: https://user-images.githubusercontent.com/973709/50965168-1d0ec500-14c9-11e9-82a0-dfee82ed0861.gif -* Search panel is hidden on small screens. +* Search panel is collapsed to mobile version on small screens. .. image:: ../static/img/search_panel.gif -Features for computers: +* Followers and send button is displayed on mobile. Avatar is hidden. -* Keyboard shortcuts for easier navigation, **using ``Alt + Shift + [key]``** - combination instead of just ``Alt + [key]``. - See https://github.com/odoo/odoo/issues/30068 to understand why. + .. image:: ../static/img/chatter.gif + +* Followers and send button is displayed on mobile. Avatar is hidden. + + .. image:: ../static/img/chatter.gif + +* Scrollable dropdowns + + .. image:: ../static/img/dropdown_scroll.gif + +* Interface is adapted dynamically on device rotation + + .. image:: ../static/img/rotate.gif + +**Features for desktop computers**: + +* Keyboard shortcuts for easier navigation, + **using `Alt + Shift + [NUM]`** combination instead of + just `Alt + [NUM]` to avoid conflict 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` .. image:: https://user-images.githubusercontent.com/973709/48417578-ff341680-e74a-11e8-8881-017709e912bc.png - -* Autofocus on search menu box when opening the drawer +* Autofocus on search menu box when opening the app menu .. image:: https://user-images.githubusercontent.com/973709/48417213-17576600-e74a-11e8-846a-57691e82636b.gif @@ -64,32 +94,8 @@ Features for computers: .. image:: ../static/img/chatter_topbar.gif -* AppMenu waits for action finished to show the view - - .. image:: ../static/img/appmenu.gif - -* Sticky header & footer in list view - - .. image:: ../static/img/listview.gif - -* Sticky statusbar in form view - - .. image:: ../static/img/formview.gif - -* Followers and send button is displayed on mobile. Avatar is hidden. - - .. image:: ../static/img/chatter.gif - * When the chatter is configured 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. .. image:: ../static/img/document_viewer.gif - -* Bigger checkboxes in list view - - .. image:: ../static/img/big_checkboxes.gif - -* Scrollable dropdowns - - .. image:: ../static/img/dropdown_scroll.gif diff --git a/web_responsive/readme/ROADMAP.rst b/web_responsive/readme/ROADMAP.rst index 389c1ec26..f27d826e4 100644 --- a/web_responsive/readme/ROADMAP.rst +++ b/web_responsive/readme/ROADMAP.rst @@ -1,7 +1,2 @@ -* To view the full experience in a device, the page must be loaded with the - device screen size. This means that, if you change the size of your browser, - you should reload the web client to get the full experience for that - new size. This is Odoo's own limitation. * App navigation with keyboard. * Handle long titles on forms in a better way -* Standard sticky headers seems to not work properly on iOS Safari/Chrome (see #1626). 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 new file mode 100644 index 000000000..1c74c6e62 --- /dev/null +++ b/web_responsive/static/src/components/apps_menu/apps_menu.esm.js @@ -0,0 +1,208 @@ +/** @odoo-module **/ +/* Copyright 2018 Tecnativa - Jairo Llopis + * Copyright 2021 ITerra - Sergey Shebanin + * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ + +import {Dropdown} from "@web/core/dropdown/dropdown"; +import {NavBar} from "@web/webclient/navbar/navbar"; +import {useAutofocus, useBus, useService} from "@web/core/utils/hooks"; +import {useHotkey} from "@web/core/hotkeys/hotkey_hook"; +import {scrollTo} from "@web/core/utils/scrolling"; +import {debounce} from "@web/core/utils/timing"; +import {fuzzyLookup} from "@web/core/utils/search"; + +const {Component} = owl; +const {useState, useRef} = owl.hooks; + +/** + * @extends Dropdown + */ +export class AppsMenu extends Dropdown { + setup() { + super.setup(); + useBus(this.env.bus, "ACTION_MANAGER:UI-UPDATED", () => this.close()); + useBus(this.env.bus, "APPS_MENU:CLOSE", () => this.close()); + } +} + +/** + * Reduce menu data to a searchable format understandable by fuzzyLookup + * + * `menuService.getMenuAsTree()` returns array in a format similar to this (only + * relevant data is shown): + * + * ```js + * // This is a menu entry: + * { + * actionID: 12, // Or `false` + * name: "Actions", + * childrenTree: {0: {...}, 1: {...}}}, // List of inner menu entries + * // in the same format or `undefined` + * } + * ``` + * + * This format is very hard to process to search matches, and it would + * slow down the search algorithm, so we reduce it with this method to be + * able to later implement a simpler search. + * + * @param {Object} memo + * Reference to current result object, passed on recursive calls. + * + * @param {Object} menu + * A menu entry, as described above. + * + * @returns {Object} + * Reduced object, without entries that have no action, and with a + * format like this: + * + * ```js + * { + * "Discuss": {Menu entry Object}, + * "Settings": {Menu entry Object}, + * "Settings/Technical/Actions/Actions": {Menu entry Object}, + * ... + * } + * ``` + */ +function findNames(memo, menu) { + if (menu.actionID) { + memo[menu.name.trim()] = menu; + } + if (menu.childrenTree) { + const innerMemo = _.reduce(menu.childrenTree, findNames, {}); + for (const innerKey in innerMemo) { + memo[menu.name.trim() + " / " + innerKey] = innerMemo[innerKey]; + } + } + return memo; +} + +/** + * @extends Component + */ +export class AppsMenuSearchBar extends Component { + setup() { + super.setup(); + this.state = useState({ + results: [], + offset: 0, + }); + useAutofocus({selector: "input"}); + this.searchBarInput = useRef("SearchBarInput"); + this._searchMenus = debounce(this._searchMenus, 100); + // Store menu data in a format searchable by fuzzy.js + this._searchableMenus = []; + this.menuService = useService("menu"); + for (const menu of this.menuService.getApps()) { + Object.assign( + this._searchableMenus, + _.reduce([this.menuService.getMenuAsTree(menu.id)], findNames, {}) + ); + } + // Set up key navigation + this._setupKeyNavigation(); + } + + willPatch() { + // Allow looping on results + if (this.state.offset < 0) { + this.state.offset = this.state.results.length + this.state.offset; + } else if (this.state.offset >= this.state.results.length) { + this.state.offset -= this.state.results.length; + } + } + + patched() { + // Scroll to selected element on keyboard navigation + if (this.state.results.length) { + const listElement = this.el.querySelector(".search-results"); + const activeElement = this.el.querySelector(".highlight"); + if (activeElement) { + scrollTo(activeElement, listElement); + } + } + } + + /** + * Search among available menu items, and render that search. + */ + _searchMenus() { + const query = this.searchBarInput.el.value; + this.state.results = + query === "" + ? [] + : fuzzyLookup(query, _.keys(this._searchableMenus), (k) => k); + } + + /** + * Get menu object for a given key. + * @param {String} key Full path to requested menu. + * @returns {Object} Menu object. + */ + _menuInfo(key) { + return this._searchableMenus[key]; + } + + /** + * Setup navigation among search results + */ + _setupKeyNavigation() { + const repeatable = { + allowRepeat: true, + }; + useHotkey( + "ArrowDown", + () => { + this.state.offset++; + }, + repeatable + ); + useHotkey( + "ArrowUp", + () => { + this.state.offset--; + }, + repeatable + ); + useHotkey( + "Tab", + () => { + this.state.offset++; + }, + repeatable + ); + useHotkey( + "Shift+Tab", + () => { + this.state.offset--; + }, + repeatable + ); + useHotkey("Home", () => { + this.state.offset = 0; + }); + useHotkey("End", () => { + this.state.offset = this.state.results.length - 1; + }); + useHotkey("Enter", () => { + if (this.state.results.length) { + this.el.querySelector(".highlight").click(); + } + }); + } + + _onKeyDown(ev) { + if (ev.code === "Escape") { + ev.stopPropagation(); + ev.preventDefault(); + const query = this.searchBarInput.el.value; + if (query) { + this.searchBarInput.el.value = ""; + } else { + this.env.bus.trigger("APPS_MENU:CLOSE"); + } + } + } +} +AppsMenuSearchBar.template = "web_responsive.AppsMenuSearchResults"; +Object.assign(NavBar.components, {AppsMenu, 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 new file mode 100644 index 000000000..0e5ccc183 --- /dev/null +++ b/web_responsive/static/src/components/apps_menu/apps_menu.scss @@ -0,0 +1,188 @@ +/* Copyright 2018 Tecnativa - Jairo Llopis + * Copyright 2021 ITerra - Sergey Shebanin + * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ + +@mixin full-screen-dropdown { + border: none; + box-shadow: none; + min-height: calc(100vh - #{$o-navbar-height}); + min-height: calc(var(--vh100, 100vh) - #{$o-navbar-height}); + position: fixed; + margin: 0; + width: 100vw; + z-index: 200; + left: 0 !important; +} + +// Iconized full screen apps menu +.o_navbar_apps_menu { + .fade-enter-active, + .fade-leave-active { + transition: opacity 100ms ease; + } + .fade-enter, + .fade-leave-to { + opacity: 0; + } + .dropdown-menu { + @include full-screen-dropdown(); + cursor: pointer; + background: url("../../img/home-menu-bg-overlay.svg"), + linear-gradient( + to bottom, + $o-brand-odoo, + desaturate(lighten($o-brand-odoo, 20%), 15) + ); + background-size: cover; + border-radius: 0; + // Display apps in a grid + align-content: flex-start; + display: flex !important; + flex-direction: row; + flex-wrap: wrap; + justify-content: flex-start; + + @include media-breakpoint-up(lg) { + padding: { + left: calc((100vw - 850px) / 2); + right: calc((100vw - 850px) / 2); + } + } + + .dropdown-item { + padding: 0; + } + + .o_app { + background: none; + img { + box-shadow: none; + margin-bottom: 5px; + transition: 300ms ease; + transition-property: box-shadow, transform; + } + + a { + outline: 0; + height: 100%; + display: flex; + align-items: center; + text-align: center; + flex-direction: column; + justify-content: flex-start; + white-space: normal; + color: gray("white") !important; + padding: 15px 0 10px; + font-size: 1.25rem; + text-shadow: 1px 1px 1px rgba(gray("black"), 0.4); + border-radius: 4px; + transition: 300ms ease; + transition-property: background-color; + background: none; + &:focus { + background-color: rgba(gray("white"), 0.05); + } + } + &:hover img, + a:focus img { + transform: translateY(-3px); + box-shadow: 0 9px 12px -4px rgba(gray("black"), 0.3); + } + + // Size depends on screen + width: 33.33333333%; + @include media-breakpoint-up(sm) { + width: 25%; + } + @include media-breakpoint-up(md) { + width: 16.6666666%; + } + } + + // Hide app icons when searching + .has-results ~ .o_app { + display: none; + } + + .o-app-icon { + height: auto; + max-width: 6rem; + padding: 0; + } + + // Search input for menus + .form-row { + width: 100%; + } + + .search-container { + width: 100%; + margin: 1rem 1.5rem 0; + + .search-input { + display: flex; + justify-items: middle; + box-shadow: inset 0 1px 0 rgba(gray("white"), 0.1), + 0 1px 0 rgba(gray("black"), 0.1); + text-shadow: 0 1px 0 rgba(gray("black"), 0.5); + border-radius: 4px; + padding: 0.4rem 0.8rem; + margin-bottom: 1rem; + background-color: rgba(gray("white"), 0.1); + + @include media-breakpoint-up(md) { + padding: 0.8rem 1.2rem; + } + + .search-icon { + color: gray("white"); + font-size: 1.5rem; + margin-right: 1rem; + padding-top: 1px; + } + + .form-control { + height: 2rem; + background: none; + border: none; + color: gray("white"); + display: block; + padding: 1px 2px 2px 2px; + box-shadow: none; + + &::placeholder { + color: gray("white"); + opacity: 0.5; + } + } + } + // Allow to scroll only on results, keeping static search box above + .search-results { + margin-top: 1rem; + max-height: calc(100vh - #{$o-navbar-height} - 8rem) !important; + overflow: auto; + position: relative; + } + .search-result { + display: block; + align-items: center; + background-position: left; + background-repeat: no-repeat; + background-size: contain; + color: gray("white"); + cursor: pointer; + line-height: 2.5rem; + padding-left: 3.5rem; + white-space: normal; + font-weight: 100; + &.highlight, + &:hover { + background-color: rgba(gray("black"), 0.11); + } + b { + font-weight: 700; + } + } + } + } +} diff --git a/web_responsive/static/src/components/apps_menu/apps_menu.xml b/web_responsive/static/src/components/apps_menu/apps_menu.xml new file mode 100644 index 000000000..86969cb5d --- /dev/null +++ b/web_responsive/static/src/components/apps_menu/apps_menu.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + +
+ + + + + + + + +
+
+ + +
+
+ + + + +
+
+
+ + + fade + + + diff --git a/web_responsive/static/src/components/attachment_viewer/attachment_viewer.esm.js b/web_responsive/static/src/components/attachment_viewer/attachment_viewer.esm.js new file mode 100644 index 000000000..6edaa0e5d --- /dev/null +++ b/web_responsive/static/src/components/attachment_viewer/attachment_viewer.esm.js @@ -0,0 +1,22 @@ +/** @odoo-module **/ +/* Copyright 2021 ITerra - Sergey Shebanin + * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ + +import {AttachmentViewer} from "@mail/components/attachment_viewer/attachment_viewer"; +import {patch} from "web.utils"; + +const {useState} = owl.hooks; + +// Patch attachment viewer to add min/max buttons capability +patch(AttachmentViewer.prototype, "web_responsive.AttachmentViewer", { + setup() { + this._super(); + this.state = useState({ + maximized: false, + }); + }, + // Disable auto-close to allow to use form in edit mode. + isCloseable() { + return false; + }, +}); diff --git a/web_responsive/static/src/components/attachment_viewer/attachment_viewer.scss b/web_responsive/static/src/components/attachment_viewer/attachment_viewer.scss new file mode 100644 index 000000000..81ebecf30 --- /dev/null +++ b/web_responsive/static/src/components/attachment_viewer/attachment_viewer.scss @@ -0,0 +1,56 @@ +/* Copyright 2019 Tecnativa - Alexandre Díaz + * Copyright 2021 ITerra - Sergey Shebanin + * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ + +// Attachment Viewer +.o_web_client.o_chatter_position_sided .o_DialogManager_dialog { + /* Show sided viewer on large screens */ + @include media-breakpoint-up(lg) { + position: static; + .o_AttachmentViewer_main { + padding-bottom: 20px; + } + .o_AttachmentViewer { + // On-top of navbar + z-index: 10; + position: absolute; + right: 0; + top: 0; + bottom: 0; + margin-left: auto; + background-color: rgba(0, 0, 0, 0.7); + + width: $chatter_zone_width; + &.o_AttachmentViewer_maximized { + width: 100%; + } + + /* Show/Hide control buttons (next, prev, etc..) */ + &:hover .o_AttachmentViewer_buttonNavigation, + &:hover .o_AttachmentViewer_toolbar { + display: flex; + } + .o_AttachmentViewer_buttonNavigation, + .o_AttachmentViewer_toolbar { + display: none; + } + .o_AttachmentViewer_viewIframe { + width: 95%; + } + } + } + @include media-breakpoint-down(md) { + .o_AttachmentViewer_headerItemButtonMinimize, + .o_AttachmentViewer_headerItemButtonMaximize { + display: none; + } + } +} + +/* Attachment Viewer Max/Min buttons only are useful in sided mode */ +.o_web_client:not(.o_chatter_position_sided) { + .o_AttachmentViewer_headerItemButtonMinimize, + .o_AttachmentViewer_headerItemButtonMaximize { + display: none; + } +} diff --git a/web_responsive/static/src/xml/attachment_viewer.xml b/web_responsive/static/src/components/attachment_viewer/attachment_viewer.xml similarity index 76% rename from web_responsive/static/src/xml/attachment_viewer.xml rename to web_responsive/static/src/components/attachment_viewer/attachment_viewer.xml index 928a1e4bf..3d26ff4e1 100644 --- a/web_responsive/static/src/xml/attachment_viewer.xml +++ b/web_responsive/static/src/components/attachment_viewer/attachment_viewer.xml @@ -3,14 +3,6 @@ Copyright 2021 Sergey Shebanin License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). -->