diff --git a/setup/web_pwa_oca/odoo/addons/web_pwa_oca b/setup/web_pwa_oca/odoo/addons/web_pwa_oca new file mode 120000 index 000000000..1b7095260 --- /dev/null +++ b/setup/web_pwa_oca/odoo/addons/web_pwa_oca @@ -0,0 +1 @@ +../../../../web_pwa_oca \ No newline at end of file diff --git a/setup/web_pwa_oca/setup.py b/setup/web_pwa_oca/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/web_pwa_oca/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/web_pwa_oca/README.rst b/web_pwa_oca/README.rst new file mode 100644 index 000000000..86d33d74a --- /dev/null +++ b/web_pwa_oca/README.rst @@ -0,0 +1,192 @@ +=========================== +Progressive web application +=========================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :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/15.0/web_pwa_oca + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-15-0/web-15-0-web_pwa_oca + :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/15.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Make Odoo an installable Progressive Web Application. + +Progressive Web Apps provide an installable, app-like experience on desktop and mobile that are built and delivered directly via the web. +They're web apps that are fast and reliable. And most importantly, they're web apps that work in any browser. +If you're building a web app today, you're already on the path towards building a Progressive Web App. + + ++ Developers Info. + +The service worker is contructed using 'Odoo Class' to have the same class inheritance behaviour that in the 'user pages'. Be noticed +that 'Odoo Bootstrap' is not supported so, you can't use 'require' here. + +All service worker content can be found in 'static/src/js/worker'. The management between 'user pages' and service worker is done in +'pwa_manager.js'. + +The purpose of this module is give a base to make PWA applications. + +**Table of contents** + +.. contents:: + :local: + +Installation +============ + +After having installed this module, browsing your odoo on mobile you will be able to install it as a PWA. + +It is strongly recommended to use this module with a responsive layout, like the one provided by web_responsive. + +This module is intended to be used by Odoo back-end users (employees). + +When a Progressive Web App is installed, it looks and behaves like all of the other installed apps. +It launches from the same place that other apps launch. It runs in an app without an address bar or other browser UI. +And like all other installed apps, it's a top level app in the task switcher. + +In Chrome, a Progressive Web App can either be installed through the three-dot context menu. + +In case you previously installed `web_pwa`, run the following steps with `odoo shell`, after having installed `openupgradelib`: + + +>>> from openupgradelib import openupgrade +>>> openupgrade.update_module_names(env.cr, [('web_pwa', 'web_pwa_oca')], merge_modules=False) +>>> env.cr.commit() + +Configuration +============= + +This module allows you to set the following parameters under settings to customize the appearance of the application + +* PWA Name (defaults to "Odoo PWA") +* PWA Short Name (defaults to "Odoo PWA") +* PWA Icon (**SVG**) (defaults to "/web_pwa_oca/static/img/icons/odoo-logo.svg") + +To configure your PWA: + +#. Go to **Settings > General Settings > Progressive Web App**. +#. Set the parameters (*Note:* Icon **must be a SVG file**) +#. **Save** + +Usage +===== + +To use your PWA: + +#. Open the Odoo web app using a supported browser (See https://caniuse.com/?search=A2HS) +#. Open the browser options +#. Click on 'Add to Home screen' (or 'Install' in other browsers) + +** Maybe you need refresh the page to load the service worker after using the option. + +Known issues / Roadmap +====================== + +* Integrate `Notification API `_ +* Integrate `Web Share API `_ +* Create ``portal_pwa`` module, intended to be used by front-end users (customers, suppliers...) +* Current *John Resig's inheritance* implementation doesn't support ``async`` + functions because ``this._super`` can't be called inside a promise. So we + need to use the following workaround: + + - Natural 'async/await' example (This breaks "_super" call): + + .. code-block:: javascript + + var MyClass = OdooClass.extend({ + myFunc: async function() { + const mydata = await ...do await stuff... + return mydata; + } + }); + + - Same code with the workaround: + + .. code-block:: javascript + + var MyClass = OdooClass.extend({ + myFunc: function() { + return new Promise(async (resolve, reject) => { + const mydata = await ...do await stuff... + return resolve(mydata); + }); + } + }); + +* Fix issue when trying to run in localhost with several databases. The browser + doesn't send the cookie and web manifest returns 404. +* Firefox can't detect 'standalone' mode. See https://bugzilla.mozilla.org/show_bug.cgi?id=1285858 +* Firefox disable service worker in private mode. See https://bugzilla.mozilla.org/show_bug.cgi?id=1601916 + +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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* TAKOBI +* Tecnativa + +Contributors +~~~~~~~~~~~~ + +* `TAKOBI `_: + + * Lorenzo Battistini + +* `Tecnativa `_: + + * Alexandre D. Díaz + * João Marques + * Sergio Teruel + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-eLBati| image:: https://github.com/eLBati.png?size=40px + :target: https://github.com/eLBati + :alt: eLBati + +Current `maintainer `__: + +|maintainer-eLBati| + +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_pwa_oca/__init__.py b/web_pwa_oca/__init__.py new file mode 100644 index 000000000..91c5580fe --- /dev/null +++ b/web_pwa_oca/__init__.py @@ -0,0 +1,2 @@ +from . import controllers +from . import models diff --git a/web_pwa_oca/__manifest__.py b/web_pwa_oca/__manifest__.py new file mode 100644 index 000000000..5cd68293a --- /dev/null +++ b/web_pwa_oca/__manifest__.py @@ -0,0 +1,27 @@ +# Copyright 2020 Lorenzo Battistini @ TAKOBI +# Copyright 2020 Tecnativa - Alexandre D. Díaz +# Copyright 2020 Tecnativa - João Marques +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). + +{ + "name": "Progressive web application", + "summary": "Make Odoo a PWA", + "version": "15.0.1.0.0", + "development_status": "Beta", + "category": "Website", + "website": "https://github.com/OCA/web", + "author": "TAKOBI, Tecnativa, Odoo Community Association (OCA)", + "maintainers": ["eLBati"], + "license": "LGPL-3", + "application": True, + "installable": True, + "depends": ["web", "mail"], + "data": ["templates/assets.xml", "views/res_config_settings_views.xml"], + "assets": { + "web.assets_backend": [ + "/web_pwa_oca/static/src/js/pwa_manager.js", + "/web_pwa_oca/static/src/js/webclient.js", + ] + }, + "images": ["static/description/pwa.png"], +} diff --git a/web_pwa_oca/controllers/__init__.py b/web_pwa_oca/controllers/__init__.py new file mode 100644 index 000000000..1fbcf85db --- /dev/null +++ b/web_pwa_oca/controllers/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2020 Lorenzo Battistini @ TAKOBI +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). +from . import main +from . import service_worker diff --git a/web_pwa_oca/controllers/main.py b/web_pwa_oca/controllers/main.py new file mode 100644 index 000000000..bb3250e24 --- /dev/null +++ b/web_pwa_oca/controllers/main.py @@ -0,0 +1,120 @@ +# Copyright 2020 Lorenzo Battistini @ TAKOBI +# Copyright 2020 Tecnativa - Alexandre D. Díaz +# Copyright 2020 Tecnativa - João Marques +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). +import json + +from odoo.http import Controller, request, route + + +class PWA(Controller): + def _get_pwa_scripts(self): + """Scripts to be imported in the service worker (Order is important)""" + return [ + "/web/static/lib/underscore/underscore.js", + "/web_pwa_oca/static/src/js/worker/jquery-sw-compat.js", + "/web/static/src/legacy/js/promise_extension.js", + "/web/static/src/boot.js", + "/web/static/src/legacy/js/core/class.js", + "/web_pwa_oca/static/src/js/worker/pwa.js", + ] + + @route("/service-worker.js", type="http", auth="public") + def render_service_worker(self): + """Route to register the service worker in the 'main' scope ('/')""" + return request.render( + "web_pwa_oca.service_worker", + { + "pwa_scripts": self._get_pwa_scripts(), + "pwa_params": self._get_pwa_params(), + }, + headers=[("Content-Type", "text/javascript;charset=utf-8")], + ) + + def _get_pwa_params(self): + """Get javascript PWA class initialzation params""" + return {} + + def _get_pwa_manifest_icons(self, pwa_icon): + icons = [] + if not pwa_icon: + for size in [ + (128, 128), + (144, 144), + (152, 152), + (192, 192), + (256, 256), + (512, 512), + ]: + icons.append( + { + "src": "/web_pwa_oca/static/img/icons/icon-%sx%s.png" + % (str(size[0]), str(size[1])), + "sizes": "{}x{}".format(str(size[0]), str(size[1])), + "type": "image/png", + "purpose": "any maskable", + } + ) + elif not pwa_icon.mimetype.startswith("image/svg"): + all_icons = ( + request.env["ir.attachment"] + .sudo() + .search( + [ + ("url", "like", "/web_pwa_oca/icon"), + ( + "url", + "not like", + "/web_pwa_oca/icon.", + ), # Get only resized icons + ] + ) + ) + for icon in all_icons: + icon_size_name = icon.url.split("/")[-1].lstrip("icon").split(".")[0] + icons.append( + {"src": icon.url, "sizes": icon_size_name, "type": icon.mimetype} + ) + else: + icons = [ + { + "src": pwa_icon.url, + "sizes": "128x128 144x144 152x152 192x192 256x256 512x512", + "type": pwa_icon.mimetype, + } + ] + return icons + + def _get_pwa_manifest(self): + """Webapp manifest""" + config_param_sudo = request.env["ir.config_parameter"].sudo() + pwa_name = config_param_sudo.get_param("pwa.manifest.name", "Odoo PWA") + pwa_short_name = config_param_sudo.get_param( + "pwa.manifest.short_name", "Odoo PWA" + ) + pwa_icon = ( + request.env["ir.attachment"] + .sudo() + .search([("url", "like", "/web_pwa_oca/icon.")]) + ) + background_color = config_param_sudo.get_param( + "pwa.manifest.background_color", "#2E69B5" + ) + theme_color = config_param_sudo.get_param("pwa.manifest.theme_color", "#2E69B5") + return { + "name": pwa_name, + "short_name": pwa_short_name, + "icons": self._get_pwa_manifest_icons(pwa_icon), + "start_url": "/web", + "display": "standalone", + "background_color": background_color, + "theme_color": theme_color, + } + + @route("/web_pwa_oca/manifest.webmanifest", type="http", auth="public") + def pwa_manifest(self): + """Returns the manifest used to install the page as app""" + return request.make_response( + json.dumps(self._get_pwa_manifest()), + headers=[("Content-Type", "application/json;charset=utf-8")], + ) diff --git a/web_pwa_oca/controllers/service_worker.py b/web_pwa_oca/controllers/service_worker.py new file mode 100644 index 000000000..1ec3e6e38 --- /dev/null +++ b/web_pwa_oca/controllers/service_worker.py @@ -0,0 +1,106 @@ +# Copyright 2021 Tecnativa - Alexandre D. Díaz +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). +from odoo.http import request, route + +from .main import PWA + + +class ServiceWorker(PWA): + + JS_PWA_CORE_EVENT_INSTALL = """ + self.addEventListener('install', evt => {{ + console.log('[ServiceWorker] Installing...'); + {} + }}); + """ + + JS_PWA_CORE_EVENT_FETCH = """ + self.addEventListener('fetch', evt => {{ + {} + }}); + """ + + JS_PWA_CORE_EVENT_ACTIVATE = """ + self.addEventListener('activate', evt => {{ + {} + }}); + """ + + JS_PWA_MAIN = """ + self.importScripts(...{pwa_scripts}); + + odoo.define("web_pwa_oca.ServiceWorker", function (require) {{ + "use strict"; + + {pwa_requires} + + {pwa_init} + {pwa_core_event_install} + {pwa_core_event_activate} + {pwa_core_event_fetch} + }}); + """ + + def _get_js_pwa_requires(self): + return """ + const PWA = require('web_pwa_oca.PWA'); + """ + + def _get_js_pwa_init(self): + return """ + let promise_start = Promise.resolve(); + if (typeof self.oca_pwa === "undefined") {{ + self.oca_pwa = new PWA({}); + promise_start = self.oca_pwa.start(); + if (self.serviceWorker.state === "activated") {{ + promise_start = promise_start.then( + () => self.oca_pwa.activateWorker(true)); + }} + }} + """.format( + self._get_pwa_params() + ) + + def _get_js_pwa_core_event_install_impl(self): + return """ + evt.waitUntil(oca_pwa.installWorker()); + self.skipWaiting(); + """ + + def _get_js_pwa_core_event_activate_impl(self): + return """ + console.log('[ServiceWorker] Activating...'); + evt.waitUntil(oca_pwa.activateWorker()); + self.clients.claim(); + """ + + def _get_js_pwa_core_event_fetch_impl(self): + return "" + + @route("/service-worker.js", type="http", auth="public") + def render_service_worker(self): + """Route to register the service worker in the 'main' scope ('/')""" + + sw_code = self.JS_PWA_MAIN.format( + **{ + "pwa_scripts": self._get_pwa_scripts(), + "pwa_requires": self._get_js_pwa_requires(), + "pwa_init": self._get_js_pwa_init(), + "pwa_core_event_install": self.JS_PWA_CORE_EVENT_INSTALL.format( + self._get_js_pwa_core_event_install_impl() + ), + "pwa_core_event_activate": self.JS_PWA_CORE_EVENT_ACTIVATE.format( + self._get_js_pwa_core_event_activate_impl() + ), + "pwa_core_event_fetch": self.JS_PWA_CORE_EVENT_FETCH.format( + self._get_js_pwa_core_event_fetch_impl() + ), + } + ) + return request.make_response( + sw_code, + [ + ("Content-Type", "text/javascript;charset=utf-8"), + ("Content-Length", len(sw_code)), + ], + ) diff --git a/web_pwa_oca/i18n/es.po b/web_pwa_oca/i18n/es.po new file mode 100644 index 000000000..63eb5388d --- /dev/null +++ b/web_pwa_oca/i18n/es.po @@ -0,0 +1,143 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_pwa_oca +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-03-16 18:49+0000\n" +"PO-Revision-Date: 2021-03-16 19:50+0100\n" +"Last-Translator: claudiagn \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 2.4.1\n" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_background_color +#, fuzzy +msgid "Background Color" +msgstr "Color de fondo" + +#. module: web_pwa_oca +#: model:ir.model,name:web_pwa_oca.model_res_config_settings +#, fuzzy +msgid "Config Settings" +msgstr "Ajustes de configuración" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_icon +#, fuzzy +msgid "Icon" +msgstr "Icono" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +#, fuzzy +msgid "Name" +msgstr "Nombre" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +#, fuzzy +msgid "Name and icon of your PWA" +msgstr "Nombre e icono de su PWA" + +#. module: web_pwa_oca +#: model:ir.model.fields,help:web_pwa_oca.field_res_config_settings__pwa_name +#, fuzzy +msgid "Name of the Progressive Web Application" +msgstr "Nombre de la aplicación web progresiva" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +#, fuzzy +msgid "PWA Title" +msgstr "Título de PWA" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +#, fuzzy +msgid "Progressive Web App" +msgstr "Aplicación web progresiva" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_name +#, fuzzy +msgid "Progressive Web App Name" +msgstr "Nombre de la aplicación web progresiva" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_short_name +#, fuzzy +msgid "Progressive Web App Short Name" +msgstr "Nombre corto de la aplicación web progresiva" + +#. module: web_pwa_oca +#. openerp-web +#: code:addons/web_pwa_oca/static/src/js/pwa_manager.js:0 +#, fuzzy, python-format +msgid "" +"Service workers are not supported! Maybe you are not using HTTPS or you work " +"in private mode." +msgstr "" +"¡Los trabajadores de servicios no son compatibles! Quizás no esté usando " +"HTTPS o trabaje en modo privado." + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +#, fuzzy +msgid "Short Name" +msgstr "Nombre corto" + +#. module: web_pwa_oca +#: model:ir.model.fields,help:web_pwa_oca.field_res_config_settings__pwa_short_name +#, fuzzy +msgid "Short Name of the Progressive Web Application" +msgstr "Nombre corto de la aplicación web progresiva" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_theme_color +#, fuzzy +msgid "Theme Color" +msgstr "Color del tema" + +#. module: web_pwa_oca +#: code:addons/web_pwa_oca/models/res_config_settings.py:0 +#, fuzzy, python-format +msgid "You can only upload PNG files bigger than 512x512" +msgstr "Solo puede cargar archivos PNG de más de 512 x 512" + +#. module: web_pwa_oca +#: code:addons/web_pwa_oca/models/res_config_settings.py:0 +#, python-format +msgid "You can only upload SVG or PNG files. Found: %s." +msgstr "" + +#. module: web_pwa_oca +#: code:addons/web_pwa_oca/models/res_config_settings.py:0 +#, fuzzy, python-format +msgid "You can't upload a file with more than 2 MB." +msgstr "No puede cargar un archivo con más de 2 MB." + +#. module: web_pwa_oca +#. openerp-web +#: code:addons/web_pwa_oca/static/src/js/pwa_manager.js:0 +#, fuzzy, python-format +msgid "[ServiceWorker] Registered:" +msgstr "[ServiceWorker] Registrada:" + +#. module: web_pwa_oca +#. openerp-web +#: code:addons/web_pwa_oca/static/src/js/pwa_manager.js:0 +#, python-format +msgid "[ServiceWorker] Registration failed: " +msgstr "[ServiceWorker] Error en el registro: " + +#, fuzzy +#~ msgid "You can only upload SVG or PNG files" +#~ msgstr "Solo puede cargar archivos SVG o PNG" diff --git a/web_pwa_oca/i18n/es_AR.po b/web_pwa_oca/i18n/es_AR.po new file mode 100644 index 000000000..c27203d68 --- /dev/null +++ b/web_pwa_oca/i18n/es_AR.po @@ -0,0 +1,128 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_pwa_oca +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-11-20 20:36+0000\n" +"Last-Translator: Ignacio Buioli \n" +"Language-Team: none\n" +"Language: es_AR\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_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_background_color +msgid "Background Color" +msgstr "Color de Fondo" + +#. module: web_pwa_oca +#: model:ir.model,name:web_pwa_oca.model_res_config_settings +msgid "Config Settings" +msgstr "Configurar Ajustes" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_icon +msgid "Icon" +msgstr "Ícono" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "Name" +msgstr "Nombre" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "Name and icon of your PWA" +msgstr "Nombre e ícono para su PWA" + +#. module: web_pwa_oca +#: model:ir.model.fields,help:web_pwa_oca.field_res_config_settings__pwa_name +msgid "Name of the Progressive Web Application" +msgstr "Nombre de la Aplicación Web Progresiva" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "PWA Title" +msgstr "Título del PWA" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "Progressive Web App" +msgstr "Aplicación Web Progresiva" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_name +msgid "Progressive Web App Name" +msgstr "Nombre de la Aplicación Web Progresiva" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_short_name +msgid "Progressive Web App Short Name" +msgstr "Nombre Corto de la Aplicación Web Progresiva" + +#. module: web_pwa_oca +#. openerp-web +#: code:addons/web_pwa_oca/static/src/js/pwa_manager.js:0 +#, python-format +msgid "" +"Service workers are not supported! Maybe you are not using HTTPS or you work " +"in private mode." +msgstr "" +"¡Los trabajadores de servicios no son compatibles! Quizás no esté usando " +"HTTPS o trabaje en modo privado." + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "Short Name" +msgstr "Nombre Corto" + +#. module: web_pwa_oca +#: model:ir.model.fields,help:web_pwa_oca.field_res_config_settings__pwa_short_name +msgid "Short Name of the Progressive Web Application" +msgstr "Nombre Corto de la Aplicación Web Progresiva" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_theme_color +msgid "Theme Color" +msgstr "Color del Tema" + +#. module: web_pwa_oca +#: code:addons/web_pwa_oca/models/res_config_settings.py:0 +#, python-format +msgid "You can only upload PNG files bigger than 512x512" +msgstr "Puede solo cargar archivos PNG mayores a 512x512" + +#. module: web_pwa_oca +#: code:addons/web_pwa_oca/models/res_config_settings.py:0 +#, python-format +msgid "You can only upload SVG or PNG files. Found: %s." +msgstr "Solo se pueden Subir archivos SVG o PNG. Se encontró: %s." + +#. module: web_pwa_oca +#: code:addons/web_pwa_oca/models/res_config_settings.py:0 +#, python-format +msgid "You can't upload a file with more than 2 MB." +msgstr "No puede cargar un archivo con un peso superior a 2 MB." + +#. module: web_pwa_oca +#. openerp-web +#: code:addons/web_pwa_oca/static/src/js/pwa_manager.js:0 +#, python-format +msgid "[ServiceWorker] Registered:" +msgstr "[ServiceWorker] Registrado:" + +#. module: web_pwa_oca +#. openerp-web +#: code:addons/web_pwa_oca/static/src/js/pwa_manager.js:0 +#, python-format +msgid "[ServiceWorker] Registration failed: " +msgstr "[ServiceWorker] Registro fallido: " + +#~ msgid "You can only upload SVG or PNG files" +#~ msgstr "Puede solo cargar archivos SVG o PNG" diff --git a/web_pwa_oca/i18n/pt_BR.po b/web_pwa_oca/i18n/pt_BR.po new file mode 100644 index 000000000..1387f7bcf --- /dev/null +++ b/web_pwa_oca/i18n/pt_BR.po @@ -0,0 +1,128 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_pwa_oca +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2022-02-01 20:33+0000\n" +"Last-Translator: Rodrigo Macedo \n" +"Language-Team: none\n" +"Language: pt_BR\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_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_background_color +msgid "Background Color" +msgstr "Cor de Fundo" + +#. module: web_pwa_oca +#: model:ir.model,name:web_pwa_oca.model_res_config_settings +msgid "Config Settings" +msgstr "Definições de Configuração" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_icon +msgid "Icon" +msgstr "Ícone" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "Name" +msgstr "Nome" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "Name and icon of your PWA" +msgstr "Nome e ícone do seu PWA" + +#. module: web_pwa_oca +#: model:ir.model.fields,help:web_pwa_oca.field_res_config_settings__pwa_name +msgid "Name of the Progressive Web Application" +msgstr "Nome da Aplicação Web Progressiva" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "PWA Title" +msgstr "Título PWA" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "Progressive Web App" +msgstr "App Web Progressivo" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_name +msgid "Progressive Web App Name" +msgstr "Nome do App Web Progressivo" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_short_name +msgid "Progressive Web App Short Name" +msgstr "Nome Curto do App Web Progressivo" + +#. module: web_pwa_oca +#. openerp-web +#: code:addons/web_pwa_oca/static/src/js/pwa_manager.js:0 +#, python-format +msgid "" +"Service workers are not supported! Maybe you are not using HTTPS or you work " +"in private mode." +msgstr "" +"Workers de servição não são suportados! Talvez você não esteja utilizando " +"HTTPS ou esteja trabalhando em modo privado." + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "Short Name" +msgstr "Nome Curto" + +#. module: web_pwa_oca +#: model:ir.model.fields,help:web_pwa_oca.field_res_config_settings__pwa_short_name +msgid "Short Name of the Progressive Web Application" +msgstr "Nome Curto da Aplicação Web Progressiva" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_theme_color +msgid "Theme Color" +msgstr "Cor do Tema" + +#. module: web_pwa_oca +#: code:addons/web_pwa_oca/models/res_config_settings.py:0 +#, python-format +msgid "You can only upload PNG files bigger than 512x512" +msgstr "Você só pode carregar arquivos PNG até 512x512" + +#. module: web_pwa_oca +#: code:addons/web_pwa_oca/models/res_config_settings.py:0 +#, python-format +msgid "You can only upload SVG or PNG files. Found: %s." +msgstr "Você só pode fazer upload de arquivos SVG ou PNG. Encontrado: %s." + +#. module: web_pwa_oca +#: code:addons/web_pwa_oca/models/res_config_settings.py:0 +#, python-format +msgid "You can't upload a file with more than 2 MB." +msgstr "Você não pode carregar um arquivo maior que 2MB." + +#. module: web_pwa_oca +#. openerp-web +#: code:addons/web_pwa_oca/static/src/js/pwa_manager.js:0 +#, python-format +msgid "[ServiceWorker] Registered:" +msgstr "[ServiceWorker] Registrado:" + +#. module: web_pwa_oca +#. openerp-web +#: code:addons/web_pwa_oca/static/src/js/pwa_manager.js:0 +#, python-format +msgid "[ServiceWorker] Registration failed: " +msgstr "[ServiceWorker] Falha no registro: " + +#~ msgid "You can only upload SVG or PNG files" +#~ msgstr "Você só pode carregar arquivos PNG ou SVG" diff --git a/web_pwa_oca/i18n/web_pwa_oca.pot b/web_pwa_oca/i18n/web_pwa_oca.pot new file mode 100644 index 000000000..a864d41f6 --- /dev/null +++ b/web_pwa_oca/i18n/web_pwa_oca.pot @@ -0,0 +1,140 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_pwa_oca +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "" +msgstr "" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_background_color +msgid "Background Color" +msgstr "" + +#. module: web_pwa_oca +#: model:ir.model,name:web_pwa_oca.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__display_name +msgid "Display Name" +msgstr "" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__id +msgid "ID" +msgstr "" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_icon +msgid "Icon" +msgstr "" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings____last_update +msgid "Last Modified on" +msgstr "" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "Name" +msgstr "" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "Name and icon of your PWA" +msgstr "" + +#. module: web_pwa_oca +#: model:ir.model.fields,help:web_pwa_oca.field_res_config_settings__pwa_name +msgid "Name of the Progressive Web Application" +msgstr "" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "PWA Title" +msgstr "" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "Progressive Web App" +msgstr "" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_name +msgid "Progressive Web App Name" +msgstr "" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_short_name +msgid "Progressive Web App Short Name" +msgstr "" + +#. module: web_pwa_oca +#. openerp-web +#: code:addons/web_pwa_oca/static/src/js/pwa_manager.js:0 +#, python-format +msgid "" +"Service workers are not supported! Maybe you are not using HTTPS or you work" +" in private mode." +msgstr "" + +#. module: web_pwa_oca +#: model_terms:ir.ui.view,arch_db:web_pwa_oca.res_config_settings_view_form +msgid "Short Name" +msgstr "" + +#. module: web_pwa_oca +#: model:ir.model.fields,help:web_pwa_oca.field_res_config_settings__pwa_short_name +msgid "Short Name of the Progressive Web Application" +msgstr "" + +#. module: web_pwa_oca +#: model:ir.model.fields,field_description:web_pwa_oca.field_res_config_settings__pwa_theme_color +msgid "Theme Color" +msgstr "" + +#. module: web_pwa_oca +#: code:addons/web_pwa_oca/models/res_config_settings.py:0 +#, python-format +msgid "You can only upload PNG files bigger than 512x512" +msgstr "" + +#. module: web_pwa_oca +#: code:addons/web_pwa_oca/models/res_config_settings.py:0 +#, python-format +msgid "You can only upload SVG or PNG files. Found: %s." +msgstr "" + +#. module: web_pwa_oca +#: code:addons/web_pwa_oca/models/res_config_settings.py:0 +#, python-format +msgid "You can't upload a file with more than 2 MB." +msgstr "" + +#. module: web_pwa_oca +#. openerp-web +#: code:addons/web_pwa_oca/static/src/js/pwa_manager.js:0 +#, python-format +msgid "[ServiceWorker] Registered:" +msgstr "" + +#. module: web_pwa_oca +#. openerp-web +#: code:addons/web_pwa_oca/static/src/js/pwa_manager.js:0 +#, python-format +msgid "[ServiceWorker] Registration failed: " +msgstr "" diff --git a/web_pwa_oca/models/__init__.py b/web_pwa_oca/models/__init__.py new file mode 100644 index 000000000..0deb68c46 --- /dev/null +++ b/web_pwa_oca/models/__init__.py @@ -0,0 +1 @@ +from . import res_config_settings diff --git a/web_pwa_oca/models/res_config_settings.py b/web_pwa_oca/models/res_config_settings.py new file mode 100644 index 000000000..946e56a72 --- /dev/null +++ b/web_pwa_oca/models/res_config_settings.py @@ -0,0 +1,159 @@ +# Copyright 2020 Tecnativa - João Marques +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). +import base64 +import io +import sys + +from PIL import Image + +from odoo import _, api, exceptions, fields, models +from odoo.tools.mimetypes import guess_mimetype + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + _pwa_icon_url_base = "/web_pwa_oca/icon" + + pwa_name = fields.Char( + "Progressive Web App Name", help="Name of the Progressive Web Application" + ) + pwa_short_name = fields.Char( + "Progressive Web App Short Name", + help="Short Name of the Progressive Web Application", + ) + pwa_icon = fields.Binary("Icon", readonly=False) + pwa_background_color = fields.Char("Background Color") + pwa_theme_color = fields.Char("Theme Color") + + @api.model + def get_values(self): + config_parameter_obj_sudo = self.env["ir.config_parameter"].sudo() + res = super(ResConfigSettings, self).get_values() + res["pwa_name"] = config_parameter_obj_sudo.get_param( + "pwa.manifest.name", default="Odoo PWA" + ) + res["pwa_short_name"] = config_parameter_obj_sudo.get_param( + "pwa.manifest.short_name", default="Odoo" + ) + pwa_icon_ir_attachment = ( + self.env["ir.attachment"] + .sudo() + .search([("url", "like", self._pwa_icon_url_base + ".")]) + ) + res["pwa_icon"] = ( + pwa_icon_ir_attachment.datas if pwa_icon_ir_attachment else False + ) + res["pwa_background_color"] = config_parameter_obj_sudo.get_param( + "pwa.manifest.background_color", default="#2E69B5" + ) + res["pwa_theme_color"] = config_parameter_obj_sudo.get_param( + "pwa.manifest.theme_color", default="#2E69B5" + ) + return res + + def _unpack_icon(self, icon): + # Wrap decoded_icon in BytesIO object + decoded_icon = base64.b64decode(icon) + icon_bytes = io.BytesIO(decoded_icon) + return Image.open(icon_bytes) + + def _write_icon_to_attachment(self, extension, mimetype, size=None): + url = self._pwa_icon_url_base + extension + icon = self.pwa_icon + # Resize image + if size: + image = self._unpack_icon(icon) + resized_image = image.resize(size) + icon_bytes_output = io.BytesIO() + resized_image.save(icon_bytes_output, format=extension.lstrip(".").upper()) + icon = base64.b64encode(icon_bytes_output.getvalue()) + url = "{}{}x{}{}".format( + self._pwa_icon_url_base, + str(size[0]), + str(size[1]), + extension, + ) + # Retreive existing attachment + existing_attachment = ( + self.env["ir.attachment"].sudo().search([("url", "like", url)]) + ) + # Write values to ir_attachment + values = { + "datas": icon, + "db_datas": icon, + "url": url, + "name": url, + "type": "binary", + "mimetype": mimetype, + } + # Rewrite if exists, else create + if existing_attachment: + existing_attachment.sudo().write(values) + else: + self.env["ir.attachment"].sudo().create(values) + + @api.model + def set_values(self): + config_parameter_obj_sudo = self.env["ir.config_parameter"].sudo() + res = super(ResConfigSettings, self).set_values() + config_parameter_obj_sudo.set_param("pwa.manifest.name", self.pwa_name) + config_parameter_obj_sudo.set_param( + "pwa.manifest.short_name", self.pwa_short_name + ) + config_parameter_obj_sudo.set_param( + "pwa.manifest.background_color", self.pwa_background_color + ) + config_parameter_obj_sudo.set_param( + "pwa.manifest.theme_color", self.pwa_theme_color + ) + # Retrieve previous value for pwa_icon from ir_attachment + pwa_icon_ir_attachments = ( + self.env["ir.attachment"] + .sudo() + .search([("url", "like", self._pwa_icon_url_base)]) + ) + # Delete or ignore if no icon provided + if not self.pwa_icon: + if pwa_icon_ir_attachments: + pwa_icon_ir_attachments.unlink() + return res + # Fail if icon provided is larger than 2mb + if sys.getsizeof(self.pwa_icon) > 2196608: + raise exceptions.UserError( + _("You can't upload a file with more than 2 MB.") + ) + # Confirm if the pwa_icon binary content is an SVG or PNG + # and process accordingly + decoded_pwa_icon = base64.b64decode(self.pwa_icon) + # Full mimetype detection + pwa_icon_mimetype = guess_mimetype(decoded_pwa_icon) + pwa_icon_extension = "." + pwa_icon_mimetype.split("/")[-1].split("+")[0] + if not pwa_icon_mimetype.startswith( + "image/svg" + ) and not pwa_icon_mimetype.startswith("image/png"): + raise exceptions.UserError( + _("You can only upload SVG or PNG files. Found: %s.") + % pwa_icon_mimetype + ) + # Delete all previous records if we are writting new ones + if pwa_icon_ir_attachments: + pwa_icon_ir_attachments.unlink() + self._write_icon_to_attachment(pwa_icon_extension, pwa_icon_mimetype) + # write multiple sizes if not SVG + if pwa_icon_extension != ".svg": + # Fail if provided PNG is smaller than 512x512 + if self._unpack_icon(self.pwa_icon).size < (512, 512): + raise exceptions.UserError( + _("You can only upload PNG files bigger than 512x512") + ) + for size in [ + (128, 128), + (144, 144), + (152, 152), + (192, 192), + (256, 256), + (512, 512), + ]: + self._write_icon_to_attachment( + pwa_icon_extension, pwa_icon_mimetype, size=size + ) diff --git a/web_pwa_oca/readme/CONFIGURE.rst b/web_pwa_oca/readme/CONFIGURE.rst new file mode 100644 index 000000000..dbd0a83f7 --- /dev/null +++ b/web_pwa_oca/readme/CONFIGURE.rst @@ -0,0 +1,11 @@ +This module allows you to set the following parameters under settings to customize the appearance of the application + +* PWA Name (defaults to "Odoo PWA") +* PWA Short Name (defaults to "Odoo PWA") +* PWA Icon (**SVG**) (defaults to "/web_pwa_oca/static/img/icons/odoo-logo.svg") + +To configure your PWA: + +#. Go to **Settings > General Settings > Progressive Web App**. +#. Set the parameters (*Note:* Icon **must be a SVG file**) +#. **Save** diff --git a/web_pwa_oca/readme/CONTRIBUTORS.rst b/web_pwa_oca/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..1484b47b2 --- /dev/null +++ b/web_pwa_oca/readme/CONTRIBUTORS.rst @@ -0,0 +1,9 @@ +* `TAKOBI `_: + + * Lorenzo Battistini + +* `Tecnativa `_: + + * Alexandre D. Díaz + * João Marques + * Sergio Teruel diff --git a/web_pwa_oca/readme/DESCRIPTION.rst b/web_pwa_oca/readme/DESCRIPTION.rst new file mode 100644 index 000000000..2b4b14ef4 --- /dev/null +++ b/web_pwa_oca/readme/DESCRIPTION.rst @@ -0,0 +1,16 @@ +Make Odoo an installable Progressive Web Application. + +Progressive Web Apps provide an installable, app-like experience on desktop and mobile that are built and delivered directly via the web. +They're web apps that are fast and reliable. And most importantly, they're web apps that work in any browser. +If you're building a web app today, you're already on the path towards building a Progressive Web App. + + ++ Developers Info. + +The service worker is contructed using 'Odoo Class' to have the same class inheritance behaviour that in the 'user pages'. Be noticed +that 'Odoo Bootstrap' is not supported so, you can't use 'require' here. + +All service worker content can be found in 'static/src/js/worker'. The management between 'user pages' and service worker is done in +'pwa_manager.js'. + +The purpose of this module is give a base to make PWA applications. diff --git a/web_pwa_oca/readme/INSTALL.rst b/web_pwa_oca/readme/INSTALL.rst new file mode 100644 index 000000000..e82e32b91 --- /dev/null +++ b/web_pwa_oca/readme/INSTALL.rst @@ -0,0 +1,18 @@ +After having installed this module, browsing your odoo on mobile you will be able to install it as a PWA. + +It is strongly recommended to use this module with a responsive layout, like the one provided by web_responsive. + +This module is intended to be used by Odoo back-end users (employees). + +When a Progressive Web App is installed, it looks and behaves like all of the other installed apps. +It launches from the same place that other apps launch. It runs in an app without an address bar or other browser UI. +And like all other installed apps, it's a top level app in the task switcher. + +In Chrome, a Progressive Web App can either be installed through the three-dot context menu. + +In case you previously installed `web_pwa`, run the following steps with `odoo shell`, after having installed `openupgradelib`: + + +>>> from openupgradelib import openupgrade +>>> openupgrade.update_module_names(env.cr, [('web_pwa', 'web_pwa_oca')], merge_modules=False) +>>> env.cr.commit() diff --git a/web_pwa_oca/readme/ROADMAP.rst b/web_pwa_oca/readme/ROADMAP.rst new file mode 100644 index 000000000..2f26e2693 --- /dev/null +++ b/web_pwa_oca/readme/ROADMAP.rst @@ -0,0 +1,35 @@ +* Integrate `Notification API `_ +* Integrate `Web Share API `_ +* Create ``portal_pwa`` module, intended to be used by front-end users (customers, suppliers...) +* Current *John Resig's inheritance* implementation doesn't support ``async`` + functions because ``this._super`` can't be called inside a promise. So we + need to use the following workaround: + + - Natural 'async/await' example (This breaks "_super" call): + + .. code-block:: javascript + + var MyClass = OdooClass.extend({ + myFunc: async function() { + const mydata = await ...do await stuff... + return mydata; + } + }); + + - Same code with the workaround: + + .. code-block:: javascript + + var MyClass = OdooClass.extend({ + myFunc: function() { + return new Promise(async (resolve, reject) => { + const mydata = await ...do await stuff... + return resolve(mydata); + }); + } + }); + +* Fix issue when trying to run in localhost with several databases. The browser + doesn't send the cookie and web manifest returns 404. +* Firefox can't detect 'standalone' mode. See https://bugzilla.mozilla.org/show_bug.cgi?id=1285858 +* Firefox disable service worker in private mode. See https://bugzilla.mozilla.org/show_bug.cgi?id=1601916 diff --git a/web_pwa_oca/readme/USAGE.rst b/web_pwa_oca/readme/USAGE.rst new file mode 100644 index 000000000..584cd8b49 --- /dev/null +++ b/web_pwa_oca/readme/USAGE.rst @@ -0,0 +1,7 @@ +To use your PWA: + +#. Open the Odoo web app using a supported browser (See https://caniuse.com/?search=A2HS) +#. Open the browser options +#. Click on 'Add to Home screen' (or 'Install' in other browsers) + +** Maybe you need refresh the page to load the service worker after using the option. diff --git a/web_pwa_oca/static/description/icon.png b/web_pwa_oca/static/description/icon.png new file mode 100644 index 000000000..2927ee1d7 Binary files /dev/null and b/web_pwa_oca/static/description/icon.png differ diff --git a/web_pwa_oca/static/description/index.html b/web_pwa_oca/static/description/index.html new file mode 100644 index 000000000..7f8ff10b0 --- /dev/null +++ b/web_pwa_oca/static/description/index.html @@ -0,0 +1,533 @@ + + + + + + +Progressive web application + + + +
+

Progressive web application

+ + +

Beta License: LGPL-3 OCA/web Translate me on Weblate Try me on Runbot

+

Make Odoo an installable Progressive Web Application.

+

Progressive Web Apps provide an installable, app-like experience on desktop and mobile that are built and delivered directly via the web. +They’re web apps that are fast and reliable. And most importantly, they’re web apps that work in any browser. +If you’re building a web app today, you’re already on the path towards building a Progressive Web App.

+
    +
  • Developers Info.
  • +
+

The service worker is contructed using ‘Odoo Class’ to have the same class inheritance behaviour that in the ‘user pages’. Be noticed +that ‘Odoo Bootstrap’ is not supported so, you can’t use ‘require’ here.

+

All service worker content can be found in ‘static/src/js/worker’. The management between ‘user pages’ and service worker is done in +‘pwa_manager.js’.

+

The purpose of this module is give a base to make PWA applications.

+

Table of contents

+ +
+

Installation

+

After having installed this module, browsing your odoo on mobile you will be able to install it as a PWA.

+

It is strongly recommended to use this module with a responsive layout, like the one provided by web_responsive.

+

This module is intended to be used by Odoo back-end users (employees).

+

When a Progressive Web App is installed, it looks and behaves like all of the other installed apps. +It launches from the same place that other apps launch. It runs in an app without an address bar or other browser UI. +And like all other installed apps, it’s a top level app in the task switcher.

+

In Chrome, a Progressive Web App can either be installed through the three-dot context menu.

+

In case you previously installed web_pwa, run the following steps with odoo shell, after having installed openupgradelib:

+
+>>> from openupgradelib import openupgrade
+>>> openupgrade.update_module_names(env.cr, [('web_pwa', 'web_pwa_oca')], merge_modules=False)
+>>> env.cr.commit()
+
+
+
+

Configuration

+

This module allows you to set the following parameters under settings to customize the appearance of the application

+
    +
  • PWA Name (defaults to “Odoo PWA”)
  • +
  • PWA Short Name (defaults to “Odoo PWA”)
  • +
  • PWA Icon (SVG) (defaults to “/web_pwa_oca/static/img/icons/odoo-logo.svg”)
  • +
+

To configure your PWA:

+
    +
  1. Go to Settings > General Settings > Progressive Web App.
  2. +
  3. Set the parameters (Note: Icon must be a SVG file)
  4. +
  5. Save
  6. +
+
+
+

Usage

+

To use your PWA:

+
    +
  1. Open the Odoo web app using a supported browser (See https://caniuse.com/?search=A2HS)
  2. +
  3. Open the browser options
  4. +
  5. Click on ‘Add to Home screen’ (or ‘Install’ in other browsers)
  6. +
+

** Maybe you need refresh the page to load the service worker after using the option.

+
+
+

Known issues / Roadmap

+
    +
  • Integrate Notification API

    +
  • +
  • Integrate Web Share API

    +
  • +
  • Create portal_pwa module, intended to be used by front-end users (customers, suppliers…)

    +
  • +
  • Current John Resig’s inheritance implementation doesn’t support async +functions because this._super can’t be called inside a promise. So we +need to use the following workaround:

    +
      +
    • Natural ‘async/await’ example (This breaks “_super” call):

      +
      +var MyClass = OdooClass.extend({
      +    myFunc: async function() {
      +        const mydata = await ...do await stuff...
      +        return mydata;
      +    }
      +});
      +
      +
    • +
    • Same code with the workaround:

      +
      +var MyClass = OdooClass.extend({
      +    myFunc: function() {
      +        return new Promise(async (resolve, reject) => {
      +            const mydata = await ...do await stuff...
      +            return resolve(mydata);
      +        });
      +    }
      +});
      +
      +
    • +
    +
  • +
  • Fix issue when trying to run in localhost with several databases. The browser +doesn’t send the cookie and web manifest returns 404.

    +
  • +
  • Firefox can’t detect ‘standalone’ mode. See https://bugzilla.mozilla.org/show_bug.cgi?id=1285858

    +
  • +
  • Firefox disable service worker in private mode. See https://bugzilla.mozilla.org/show_bug.cgi?id=1601916

    +
  • +
+
+
+

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.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • TAKOBI
  • +
  • Tecnativa
  • +
+
+
+

Contributors

+
    +
  • TAKOBI:
      +
    • Lorenzo Battistini
    • +
    +
  • +
  • Tecnativa:
      +
    • Alexandre D. Díaz
    • +
    • João Marques
    • +
    • Sergio Teruel
    • +
    +
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

eLBati

+

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_pwa_oca/static/description/pwa.png b/web_pwa_oca/static/description/pwa.png new file mode 100644 index 000000000..0591fd870 Binary files /dev/null and b/web_pwa_oca/static/description/pwa.png differ diff --git a/web_pwa_oca/static/img/icons/icon-128x128.png b/web_pwa_oca/static/img/icons/icon-128x128.png new file mode 100644 index 000000000..b111f3697 Binary files /dev/null and b/web_pwa_oca/static/img/icons/icon-128x128.png differ diff --git a/web_pwa_oca/static/img/icons/icon-144x144.png b/web_pwa_oca/static/img/icons/icon-144x144.png new file mode 100644 index 000000000..dd3fd020d Binary files /dev/null and b/web_pwa_oca/static/img/icons/icon-144x144.png differ diff --git a/web_pwa_oca/static/img/icons/icon-152x152.png b/web_pwa_oca/static/img/icons/icon-152x152.png new file mode 100644 index 000000000..38023d8cf Binary files /dev/null and b/web_pwa_oca/static/img/icons/icon-152x152.png differ diff --git a/web_pwa_oca/static/img/icons/icon-192x192.png b/web_pwa_oca/static/img/icons/icon-192x192.png new file mode 100644 index 000000000..4d46abbfb Binary files /dev/null and b/web_pwa_oca/static/img/icons/icon-192x192.png differ diff --git a/web_pwa_oca/static/img/icons/icon-256x256.png b/web_pwa_oca/static/img/icons/icon-256x256.png new file mode 100644 index 000000000..a54e9d6fd Binary files /dev/null and b/web_pwa_oca/static/img/icons/icon-256x256.png differ diff --git a/web_pwa_oca/static/img/icons/icon-512x512.png b/web_pwa_oca/static/img/icons/icon-512x512.png new file mode 100644 index 000000000..3be61eacb Binary files /dev/null and b/web_pwa_oca/static/img/icons/icon-512x512.png differ diff --git a/web_pwa_oca/static/img/icons/odoo_logo.svg b/web_pwa_oca/static/img/icons/odoo_logo.svg new file mode 100644 index 000000000..8a705eaf5 --- /dev/null +++ b/web_pwa_oca/static/img/icons/odoo_logo.svg @@ -0,0 +1,67 @@ + + + + + + image/svg+xml + + + + + + + + + + + +