diff --git a/web_responsive/README.rst b/web_responsive/README.rst index ab87b38e3..d5c387cdf 100644 --- a/web_responsive/README.rst +++ b/web_responsive/README.rst @@ -14,13 +14,13 @@ 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/12.0/web_responsive + :target: https://github.com/OCA/web/tree/13.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-12-0/web-12-0-web_responsive + :target: https://translation.odoo-community.org/projects/web-13-0/web-13-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/12.0 + :target: https://runbot.odoo-community.org/runbot/162/13.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -85,23 +85,23 @@ Features for computers: * Sticky chatter topbar - .. image:: https://raw.githubusercontent.com/OCA/web/12.0/web_responsive/static/img/chatter_topbar.gif + .. image:: https://raw.githubusercontent.com/OCA/web/13.0/web_responsive/static/img/chatter_topbar.gif * AppMenu waits for action finished to show the view - .. image:: https://raw.githubusercontent.com/OCA/web/12.0/web_responsive/static/img/appmenu.gif + .. image:: https://raw.githubusercontent.com/OCA/web/13.0/web_responsive/static/img/appmenu.gif * Sticky header & footer in list view - .. image:: https://raw.githubusercontent.com/OCA/web/12.0/web_responsive/static/img/listview.gif + .. image:: https://raw.githubusercontent.com/OCA/web/13.0/web_responsive/static/img/listview.gif * Sticky statusbar in form view - .. image:: https://raw.githubusercontent.com/OCA/web/12.0/web_responsive/static/img/formview.gif + .. image:: https://raw.githubusercontent.com/OCA/web/13.0/web_responsive/static/img/formview.gif * Followers and send button is displayed on mobile. Avatar is hidden. - .. image:: https://raw.githubusercontent.com/OCA/web/12.0/web_responsive/static/img/chatter.gif + .. image:: https://raw.githubusercontent.com/OCA/web/13.0/web_responsive/static/img/chatter.gif **Table of contents** @@ -113,7 +113,6 @@ Usage The following keyboard shortcuts are implemented: -* Toggle app drawer - ``Alt + Shift + H`` * Navigate app search results - Arrow keys * Choose app result - ``Enter`` * ``Esc`` to close app drawer @@ -134,7 +133,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. @@ -146,7 +145,6 @@ Authors * LasLabs * Tecnativa -* Alexandre Díaz Contributors ~~~~~~~~~~~~ @@ -171,6 +169,6 @@ 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. -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 64536b024..afcfa70b6 100644 --- a/web_responsive/__manifest__.py +++ b/web_responsive/__manifest__.py @@ -1,14 +1,14 @@ # Copyright 2016-2017 LasLabs Inc. -# Copyright 2018 Alexandre Díaz +# Copyright 2018-2019 Alexandre Díaz # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). { "name": "Web Responsive", "summary": "Responsive web client, community-supported", - "version": "12.0.1.3.0", + "version": "13.0.1.0.0", "category": "Website", "website": "https://github.com/OCA/web", - "author": "LasLabs, Tecnativa, Alexandre Díaz, " + "author": "LasLabs, Tecnativa, " "Odoo Community Association (OCA)", "license": "LGPL-3", "installable": True, diff --git a/web_responsive/models/res_users.py b/web_responsive/models/res_users.py index 7b80a9790..8075e039f 100644 --- a/web_responsive/models/res_users.py +++ b/web_responsive/models/res_users.py @@ -1,4 +1,4 @@ -# Copyright 2018 Alexandre Díaz +# Copyright 2018-2019 Alexandre Díaz # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import models, fields @@ -10,7 +10,7 @@ class ResUsers(models.Model): chatter_position = fields.Selection([ ('normal', 'Normal'), ('sided', 'Sided'), - ], string="Chatter Position", default='normal') + ], string="Chatter Position", default='sided') def __init__(self, pool, cr): """ Override of __init__ to add access rights. diff --git a/web_responsive/readme/USAGE.rst b/web_responsive/readme/USAGE.rst index a8a1c12bd..ef87cbe59 100644 --- a/web_responsive/readme/USAGE.rst +++ b/web_responsive/readme/USAGE.rst @@ -1,6 +1,5 @@ The following keyboard shortcuts are implemented: -* Toggle app drawer - ``Alt + Shift + H`` * Navigate app search results - Arrow keys * Choose app result - ``Enter`` * ``Esc`` to close app drawer diff --git a/web_responsive/static/description/index.html b/web_responsive/static/description/index.html index e9ebd0c66..6c23c0c4d 100644 --- a/web_responsive/static/description/index.html +++ b/web_responsive/static/description/index.html @@ -367,7 +367,7 @@ ul.auto-toc { !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

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

+

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

This module adds responsiveness to web backend.

Features for all devices:

Table of contents

@@ -449,7 +449,6 @@ See
Usage

The following keyboard shortcuts are implemented:

    -
  • Toggle app drawer - Alt + Shift + H
  • Navigate app search results - Arrow keys
  • Choose app result - Enter
  • Esc to close app drawer
  • @@ -471,7 +470,7 @@ new size. This is Odoo’s own limitation.

    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.

    @@ -481,7 +480,6 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
    • LasLabs
    • Tecnativa
    • -
    • Alexandre Díaz
    @@ -502,7 +500,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

    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.

    -

    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/static/src/css/web_responsive.scss b/web_responsive/static/src/css/web_responsive.scss index 035b7811b..decd12684 100644 --- a/web_responsive/static/src/css/web_responsive.scss +++ b/web_responsive/static/src/css/web_responsive.scss @@ -207,12 +207,12 @@ } // Scroll all but top bar -html .o_web_client .o_main .o_main_content { +html .o_web_client .o_action_manager .o_action { @include media-breakpoint-down(sm) { overflow: auto; .o_content { - overflow: initial; + overflow: visible; } } @@ -330,13 +330,10 @@ html .o_web_client .o_main .o_main_content { .o_form_sheet { max-width: calc(100% - 32px); overflow-x: auto; + } - .oe_button_box { - .o_dropdown_more { - padding: 0.1em; - width: min-content; - } - } + .oe_chatter { + padding-top: 0; } // Sticky statusbar @@ -365,8 +362,16 @@ html .o_web_client .o_main .o_main_content { @include media-breakpoint-down(sm) { min-width: auto; + // More buttons border + .oe_button_box { + .o_dropdown_more { + button:last-child { + border-right: 1px solid gray('400'); + } + } + } + // Avoid overflow on forms with title and/or button box - .oe_button_box, .oe_title, { max-width: 100%; @@ -432,6 +437,8 @@ html .o_web_client .o_main .o_main_content { } .o_chatter { + padding-top: initial; + // Display send button on small screens .o_thread_composer { padding-left: $o-mail-thread-avatar-size*0.5; @@ -497,22 +504,7 @@ html .o_web_client .o_main .o_main_content { position: sticky; background-color: $o-view-background-color; z-index: 1; - - .o_chatter_topbar { - margin-top: 0; - flex-wrap: wrap; - height: auto; - button:last-of-type { - flex: 1 0 auto; - text-align: left; - } - - .o_topbar_right_area { - order: -10; - flex: 0 1 100%; - border-bottom-color: transparent; - } - } + overflow-x: auto; .o_attachments_previews { overflow: auto; @@ -526,25 +518,25 @@ html .o_web_client .o_main .o_main_content { } // Sticky Header & Footer in List View -.table-responsive { - overflow-x: initial; - - .o_list_view { - // th & td are here for compatibility with chrome - thead, thead tr:nth-child(1) th { - position: sticky; - top: 0; - z-index: 1; - } - thead tr:nth-child(1) th { - background-color: $o-list-footer-bg-color; - } - tfoot, tfoot tr:nth-child(1) td { - position: sticky; - bottom: 0; - } - tfoot tr:nth-child(1) td { - background-color: $o-list-footer-bg-color; +.o_list_view { + .table-responsive { + .o_list_table { + // th & td are here for compatibility with chrome + thead, thead tr:nth-child(1) th { + position: sticky; + top: 0; + z-index: 1; + } + thead tr:nth-child(1) th { + background-color: $o-list-footer-bg-color; + } + tfoot, tfoot tr:nth-child(1) td { + position: sticky; + bottom: 0; + } + tfoot tr:nth-child(1) td { + background-color: $o-list-footer-bg-color; + } } } } diff --git a/web_responsive/static/src/js/web_responsive.js b/web_responsive/static/src/js/web_responsive.js index 0d9bfa793..2261780a4 100644 --- a/web_responsive/static/src/js/web_responsive.js +++ b/web_responsive/static/src/js/web_responsive.js @@ -4,16 +4,17 @@ odoo.define('web_responsive', function (require) { 'use strict'; - var ActionManager = require('web.ActionManager'); - var AbstractWebClient = require("web.AbstractWebClient"); - var AppsMenu = require("web.AppsMenu"); - var BasicController = require('web.BasicController'); - var config = require("web.config"); - var core = require("web.core"); - var FormRenderer = require('web.FormRenderer'); - var Menu = require("web.Menu"); - var RelationalFields = require('web.relational_fields'); - var Chatter = require('mail.Chatter'); + const ActionManager = require('web.ActionManager'); + const AbstractWebClient = require("web.AbstractWebClient"); + const AppsMenu = require("web.AppsMenu"); + const BasicController = require('web.BasicController'); + const config = require("web.config"); + const core = require("web.core"); + const FormRenderer = require('web.FormRenderer'); + const Menu = require("web.Menu"); + const RelationalFields = require('web.relational_fields'); + const Chatter = require('mail.Chatter'); + const ListRenderer = require('web.ListRenderer'); /* * Helper function to know if are waiting @@ -97,7 +98,7 @@ odoo.define('web_responsive', function (require) { init: function (parent, menuData) { this._super.apply(this, arguments); // Keep base64 icon for main menus - for (var n in this._apps) { + for (let n in this._apps) { this._apps[n].web_icon_data = menuData.children[n].web_icon_data; } @@ -108,7 +109,7 @@ odoo.define('web_responsive', function (require) { {} ); // Search only after timeout, for fast typers - this._search_def = $.Deferred(); + this._search_def = false; }, /** @@ -141,7 +142,7 @@ odoo.define('web_responsive', function (require) { * Menu definition, plus extra needed keys. */ _menuInfo: function (key) { - var original = this._searchableMenus[key]; + const original = this._searchableMenus[key]; return _.extend({ action_id: parseInt(original.action.split(',')[1], 10), }, original); @@ -169,17 +170,17 @@ odoo.define('web_responsive', function (require) { * Schedule a search on current menu items. */ _searchMenusSchedule: function () { - this._search_def.reject(); - this._search_def = $.Deferred(); - setTimeout(this._search_def.resolve.bind(this._search_def), 50); - this._search_def.done(this._searchMenus.bind(this)); + this._search_def = new Promise((resolve) => { + setTimeout(resolve, 50); + }); + this._search_def.then(this._searchMenus.bind(this)); }, /** * Search among available menu items, and render that search. */ _searchMenus: function () { - var query = this.$search_input.val(); + const query = this.$search_input.val(); if (query === "") { this.$search_container.removeClass("has-results"); this.$search_results.empty(); @@ -216,7 +217,7 @@ odoo.define('web_responsive', function (require) { _searchResultChosen: function (event) { event.preventDefault(); event.stopPropagation(); - var $result = $(event.currentTarget), + const $result = $(event.currentTarget), text = $result.text().trim(), data = $result.data(), suffix = ~text.indexOf("/") ? "/" : ""; @@ -227,7 +228,7 @@ odoo.define('web_responsive', function (require) { previous_menu_id: data.parentId, }); // Find app that owns the chosen menu - var app = _.find(this._apps, function (_app) { + const app = _.find(this._apps, function (_app) { return text.indexOf(_app.name + suffix) === 0; }); // Update navbar menus @@ -241,9 +242,9 @@ odoo.define('web_responsive', function (require) { */ _searchResultsNavigate: function (event) { // Find current results and active element (1st by default) - var all = this.$search_results.find(".o-menu-search-result"), - pre_focused = all.filter(".active") || $(all[0]), - offset = all.index(pre_focused), + const all = this.$search_results.find(".o-menu-search-result"), + pre_focused = all.filter(".active") || $(all[0]); + let offset = all.index(pre_focused), key = event.key; // Keyboard navigation only supports search results if (!all.length) { @@ -277,7 +278,7 @@ odoo.define('web_responsive', function (require) { offset -= all.length; } // Switch active element - var new_focused = $(all[offset]); + const new_focused = $(all[offset]); pre_focused.removeClass("active"); new_focused.addClass("active"); this.$search_results.scrollTo(new_focused, { @@ -298,14 +299,17 @@ odoo.define('web_responsive', function (require) { BasicController.include({ /** - * Close the AppDrawer if the data set is dirty and a discard dialog is opened + * Close the AppDrawer if the data set is dirty and a discard dialog + * is opened * * @override */ canBeDiscarded: function (recordID) { if (this.model.isDirty(recordID || this.handle)) { - $('.o_menu_apps .dropdown:has(.dropdown-menu.show) > a').dropdown('toggle'); - $('.o_menu_sections li.show .dropdown-toggle').dropdown('toggle'); + $('.o_menu_apps .dropdown:has(.dropdown-menu.show) > a') + .dropdown('toggle'); + $('.o_menu_sections li.show .dropdown-toggle') + .dropdown('toggle'); } return this._super.apply(this, arguments); }, @@ -382,13 +386,38 @@ odoo.define('web_responsive', function (require) { _setState: function () { this._super.apply(this, arguments); if (config.device.isMobile) { - _.map(this.status_information, function (value) { + _.map(this.status_information, (value) => { value.fold = true; }); } }, }); + // Sticky Column Selector + ListRenderer.include({ + _renderView: function () { + const self = this; + return this._super.apply(this, arguments).then(() => { + const $col_selector = self.$el.find( + '.o_optional_columns_dropdown_toggle'); + if ($col_selector.length !== 0) { + const $th = self.$el.find('thead>tr:first>th:last'); + $col_selector.appendTo($th); + } + }); + }, + + _onToggleOptionalColumnDropdown: function (ev) { + // FIXME: For some strange reason the 'stopPropagation' call + // in the main method don't work. Invoking here the same method + // does the expected behavior... O_O! + // This prevents the action of sorting the column from being + // launched. + ev.stopPropagation(); + this._super.apply(this, arguments); + }, + }); + // Responsive view "action" buttons FormRenderer.include({ @@ -398,7 +427,7 @@ odoo.define('web_responsive', function (require) { * @override */ _renderHeaderButtons: function () { - var $buttons = this._super.apply(this, arguments); + const $buttons = this._super.apply(this, arguments); if ( !config.device.isMobile || !$buttons.is(":has(>:not(.o_invisible_modifier))") @@ -408,7 +437,7 @@ odoo.define('web_responsive', function (require) { // $buttons must be appended by JS because all events are bound $buttons.addClass("dropdown-menu"); - var $dropdown = $(core.qweb.render( + const $dropdown = $(core.qweb.render( 'web_responsive.MenuStatusbarButtons' )); $buttons.addClass("dropdown-menu").appendTo($dropdown); @@ -442,26 +471,25 @@ odoo.define('web_responsive', function (require) { * The executed action */ _hideMenusByAction: function (action) { - var uniq_sel = '[data-action-id='+action.id+']'; + const uniq_sel = '[data-action-id='+action.id+']'; // Need close AppDrawer? - var menu_apps_dropdown = document.querySelector( + const menu_apps_dropdown = document.querySelector( '.o_menu_apps .dropdown'); $(menu_apps_dropdown).has('.dropdown-menu.show') .has(uniq_sel).find('> a').dropdown('toggle'); // Need close Sections Menu? - // TODO: Change to 'hide' in modern Bootstrap >4.1 - var menu_sections = document.querySelector( + const menu_sections = document.querySelector( '.o_menu_sections li.show'); $(menu_sections).has(uniq_sel).find('.dropdown-toggle') .dropdown('toggle'); // Need close Mobile? - var menu_sections_mobile = document.querySelector( + const menu_sections_mobile = document.querySelector( '.o_menu_sections.show'); - $(menu_sections_mobile).has(uniq_sel).collapse('hide'); + $(menu_sections_mobile).has(uniq_sel).hide(); }, _handleAction: function (action) { - return this._super.apply(this, arguments).always( + return this._super.apply(this, arguments).finally( $.proxy(this, '_hideMenusByAction', action)); }, }); @@ -498,7 +526,7 @@ odoo.define('web_responsive', function (require) { * Altered event object */ _shiftPressed: function (keyEvent) { - var alt = keyEvent.altKey || keyEvent.key === "Alt", + const alt = keyEvent.altKey || keyEvent.key === "Alt", newEvent = _.extend({}, keyEvent), shift = keyEvent.shiftKey || keyEvent.key === "Shift"; // Mock event to make it seem like Alt is not pressed diff --git a/web_responsive/tests/test_res_users.py b/web_responsive/tests/test_res_users.py index 6f4f03221..872a6c5a4 100644 --- a/web_responsive/tests/test_res_users.py +++ b/web_responsive/tests/test_res_users.py @@ -9,8 +9,8 @@ class TestResUsers(common.TransactionCase): def test_chatter_position_wr(self): user_public = self.env.ref('base.public_user') - self.assertEqual(user_public.chatter_position, 'normal') - user_public.sudo(user_public).write({ - 'chatter_position': 'sided', - }) self.assertEqual(user_public.chatter_position, 'sided') + user_public.sudo(user_public).write({ + 'chatter_position': 'normal', + }) + self.assertEqual(user_public.chatter_position, 'normal') diff --git a/web_responsive/views/web.xml b/web_responsive/views/web.xml index 6e7967f45..0faf3b44a 100644 --- a/web_responsive/views/web.xml +++ b/web_responsive/views/web.xml @@ -11,8 +11,8 @@ inherit_id="web.webclient_bootstrap" name="App Drawer - Web Client" > - - o_main o_chatter_position_{{ request.env.user.chatter_position or 'normal' }} + +