diff --git a/web_company_context_highlight/README.rst b/web_company_context_highlight/README.rst new file mode 100644 index 00000000000..77240fef677 --- /dev/null +++ b/web_company_context_highlight/README.rst @@ -0,0 +1,128 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +============================= +Web Company Context Highlight +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:38a53b982d2d8c282f7bee4b39e8df7f2324ab0ef62629ea37a4baa6d9ee457f + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/license-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/19.0/web_company_context_highlight + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-19-0/web-19-0-web_company_context_highlight + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=19.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module highlights the company switcher in the top bar of the web +client when multiple companies are selected. + +In a multi-company Odoo environment, users can easily lose track of +their active company context. When more than one company is selected, +they might unintentionally create or view records in the wrong context. + +By applying a visual highlight to the company switcher when multiple +companies are selected, this module provides an immediate visual cue, +helping users remain aware of their active companies and reducing the +risk of data entry errors. + +- with multiple companies selected + + |company switcher with multiple companies selected| + +- with one company selected + + |company switcher with one company selected| + +.. |company switcher with multiple companies selected| image:: https://raw.githubusercontent.com/OCA/web/19.0/web_company_context_highlight/static/img/web_company_context_highlight_multiple_companies_selected.png +.. |company switcher with one company selected| image:: https://raw.githubusercontent.com/OCA/web/19.0/web_company_context_highlight/static/img/web_company_context_highlight_one_company_selected.png + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +To configure the highlight colors: + +1. Go to **Settings** > **General Settings**. +2. Scroll to the **Companies** section. +3. Under **Company Switcher Highlight**, set the desired **Background + Color** and **Text Color** using the color pickers. +4. Click **Save**. + +|color configuration| + +Alternatively, you can configure these values by modifying the following +System Parameters (in debug mode, under **Settings** > **Technical** > +**System Parameters**): + +- ``web_company_context_highlight.color``: The background color code + (default: ``#ffc107``). +- ``web_company_context_highlight.text_color``: The text color code + (default: ``#212529``). + +.. |color configuration| image:: https://raw.githubusercontent.com/OCA/web/19.0/web_company_context_highlight/static/img/web_company_context_highlight_config_color.png + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Acsone + +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-pverkest| image:: https://github.com/pverkest.png?size=40px + :target: https://github.com/pverkest + :alt: pverkest + +Current `maintainer `__: + +|maintainer-pverkest| + +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_company_context_highlight/__init__.py b/web_company_context_highlight/__init__.py new file mode 100644 index 00000000000..7d768b54b0a --- /dev/null +++ b/web_company_context_highlight/__init__.py @@ -0,0 +1,3 @@ +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from . import models diff --git a/web_company_context_highlight/__manifest__.py b/web_company_context_highlight/__manifest__.py new file mode 100644 index 00000000000..b807eac5a2b --- /dev/null +++ b/web_company_context_highlight/__manifest__.py @@ -0,0 +1,26 @@ +# Copyright 2026 Acsone +# @author Pierre Verkest +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + "name": "Web Company Context Highlight", + "summary": "Highlight the company switcher when multiple companies are selected", + "version": "19.0.1.0.0", + "author": "Acsone, Odoo Community Association (OCA)", + "maintainers": ["pverkest"], + "website": "https://github.com/OCA/web", + "license": "LGPL-3", + "category": "Web", + "depends": ["web", "base_setup"], + "data": ["views/res_config_settings_views.xml"], + "assets": { + "web.assets_backend": [ + "web_company_context_highlight/static/src/**/*.js", + "web_company_context_highlight/static/src/**/*.scss", + "web_company_context_highlight/static/src/**/*.xml", + ], + "web.assets_tests": [ + "web_company_context_highlight/static/tests/tours/**/*.js", + ], + }, +} diff --git a/web_company_context_highlight/models/__init__.py b/web_company_context_highlight/models/__init__.py new file mode 100644 index 00000000000..c8ef769857e --- /dev/null +++ b/web_company_context_highlight/models/__init__.py @@ -0,0 +1,4 @@ +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from . import ir_http +from . import res_config_settings diff --git a/web_company_context_highlight/models/ir_http.py b/web_company_context_highlight/models/ir_http.py new file mode 100644 index 00000000000..6c48fba0376 --- /dev/null +++ b/web_company_context_highlight/models/ir_http.py @@ -0,0 +1,25 @@ +# Copyright 2026 Acsone +# @author Pierre Verkest +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo import models + + +class IrHttp(models.AbstractModel): + _inherit = "ir.http" + + def session_info(self): + session = super().session_info() + highlight_color = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("web_company_context_highlight.color", "#ffc107") + ) + text_color = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("web_company_context_highlight.text_color", "#212529") + ) + session["web_company_context_highlight_color"] = highlight_color + session["web_company_context_highlight_text_color"] = text_color + return session diff --git a/web_company_context_highlight/models/res_config_settings.py b/web_company_context_highlight/models/res_config_settings.py new file mode 100644 index 00000000000..2cedb53f024 --- /dev/null +++ b/web_company_context_highlight/models/res_config_settings.py @@ -0,0 +1,24 @@ +# Copyright 2026 Acsone +# @author Pierre Verkest +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + web_company_context_highlight_color = fields.Char( + string="Company Highlight Color", + default="#ffc107", + config_parameter="web_company_context_highlight.color", + help="Background color used to highlight the company switcher " + "when in multi-company context.", + ) + web_company_context_highlight_text_color = fields.Char( + string="Company Highlight Text Color", + default="#212529", + config_parameter="web_company_context_highlight.text_color", + help="Text color used to highlight the company switcher " + "when in multi-company context.", + ) diff --git a/web_company_context_highlight/pyproject.toml b/web_company_context_highlight/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/web_company_context_highlight/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/web_company_context_highlight/readme/CONFIGURE.md b/web_company_context_highlight/readme/CONFIGURE.md new file mode 100644 index 00000000000..af3cb366e73 --- /dev/null +++ b/web_company_context_highlight/readme/CONFIGURE.md @@ -0,0 +1,13 @@ +To configure the highlight colors: + +1. Go to **Settings** > **General Settings**. +2. Scroll to the **Companies** section. +3. Under **Company Switcher Highlight**, set the desired **Background Color** and **Text Color** using the color pickers. +4. Click **Save**. + +![color configuration](../static/img/web_company_context_highlight_config_color.png) + +Alternatively, you can configure these values by modifying the following System Parameters (in debug mode, under **Settings** > **Technical** > **System Parameters**): + +* `web_company_context_highlight.color`: The background color code (default: `#ffc107`). +* `web_company_context_highlight.text_color`: The text color code (default: `#212529`). diff --git a/web_company_context_highlight/readme/DESCRIPTION.md b/web_company_context_highlight/readme/DESCRIPTION.md new file mode 100644 index 00000000000..3fd9c4e3b6c --- /dev/null +++ b/web_company_context_highlight/readme/DESCRIPTION.md @@ -0,0 +1,13 @@ +This module highlights the company switcher in the top bar of the web client when multiple companies are selected. + +In a multi-company Odoo environment, users can easily lose track of their active company context. When more than one company is selected, they might unintentionally create or view records in the wrong context. + +By applying a visual highlight to the company switcher when multiple companies are selected, this module provides an immediate visual cue, helping users remain aware of their active companies and reducing the risk of data entry errors. + +* with multiple companies selected + + ![company switcher with multiple companies selected](../static/img/web_company_context_highlight_multiple_companies_selected.png) + +* with one company selected + + ![company switcher with one company selected](../static/img/web_company_context_highlight_one_company_selected.png) diff --git a/web_company_context_highlight/static/description/index.html b/web_company_context_highlight/static/description/index.html new file mode 100644 index 00000000000..5a1b0b2e6b2 --- /dev/null +++ b/web_company_context_highlight/static/description/index.html @@ -0,0 +1,462 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Web Company Context Highlight

+ +

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

+

This module highlights the company switcher in the top bar of the web +client when multiple companies are selected.

+

In a multi-company Odoo environment, users can easily lose track of +their active company context. When more than one company is selected, +they might unintentionally create or view records in the wrong context.

+

By applying a visual highlight to the company switcher when multiple +companies are selected, this module provides an immediate visual cue, +helping users remain aware of their active companies and reducing the +risk of data entry errors.

+
    +
  • with multiple companies selected

    +

    company switcher with multiple companies selected

    +
  • +
  • with one company selected

    +

    company switcher with one company selected

    +
  • +
+

Table of contents

+ +
+

Configuration

+

To configure the highlight colors:

+
    +
  1. Go to Settings > General Settings.
  2. +
  3. Scroll to the Companies section.
  4. +
  5. Under Company Switcher Highlight, set the desired Background +Color and Text Color using the color pickers.
  6. +
  7. Click Save.
  8. +
+

color configuration

+

Alternatively, you can configure these values by modifying the following +System Parameters (in debug mode, under Settings > Technical > +System Parameters):

+
    +
  • web_company_context_highlight.color: The background color code +(default: #ffc107).
  • +
  • web_company_context_highlight.text_color: The text color code +(default: #212529).
  • +
+
+
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Acsone
  • +
+
+
+

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:

+

pverkest

+

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_company_context_highlight/static/img/web_company_context_highlight_config_color.png b/web_company_context_highlight/static/img/web_company_context_highlight_config_color.png new file mode 100644 index 00000000000..528c812538f Binary files /dev/null and b/web_company_context_highlight/static/img/web_company_context_highlight_config_color.png differ diff --git a/web_company_context_highlight/static/img/web_company_context_highlight_multiple_companies_selected.png b/web_company_context_highlight/static/img/web_company_context_highlight_multiple_companies_selected.png new file mode 100644 index 00000000000..fdd0214a0c4 Binary files /dev/null and b/web_company_context_highlight/static/img/web_company_context_highlight_multiple_companies_selected.png differ diff --git a/web_company_context_highlight/static/img/web_company_context_highlight_one_company_selected.png b/web_company_context_highlight/static/img/web_company_context_highlight_one_company_selected.png new file mode 100644 index 00000000000..3c28466b35b Binary files /dev/null and b/web_company_context_highlight/static/img/web_company_context_highlight_one_company_selected.png differ diff --git a/web_company_context_highlight/static/src/js/switch_company_menu.esm.js b/web_company_context_highlight/static/src/js/switch_company_menu.esm.js new file mode 100644 index 00000000000..a729f699e9d --- /dev/null +++ b/web_company_context_highlight/static/src/js/switch_company_menu.esm.js @@ -0,0 +1,17 @@ +/** + * Copyright 2026 Acsone + * @author Pierre Verkest + * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ + +import {SwitchCompanyMenu} from "@web/webclient/switch_company_menu/switch_company_menu"; +import {patch} from "@web/core/utils/patch"; +import {session} from "@web/session"; + +patch(SwitchCompanyMenu.prototype, { + setup() { + super.setup(); + this.highlightColor = session.web_company_context_highlight_color || "#ffc107"; + this.highlightTextColor = + session.web_company_context_highlight_text_color || "#212529"; + }, +}); diff --git a/web_company_context_highlight/static/src/scss/switch_company_menu.scss b/web_company_context_highlight/static/src/scss/switch_company_menu.scss new file mode 100644 index 00000000000..18a17b9e823 --- /dev/null +++ b/web_company_context_highlight/static/src/scss/switch_company_menu.scss @@ -0,0 +1,10 @@ +.o_switch_company_menu.o_company_context_highlighted { + button { + background-color: var(--o-company-context-highlight-bg, #ffc107) !important; + color: var(--o-company-context-highlight-color, #212529) !important; + border-radius: 4px; + font-weight: bold; + padding-left: 6px; + padding-right: 6px; + } +} diff --git a/web_company_context_highlight/static/src/xml/switch_company_menu.xml b/web_company_context_highlight/static/src/xml/switch_company_menu.xml new file mode 100644 index 00000000000..771f2ad4a08 --- /dev/null +++ b/web_company_context_highlight/static/src/xml/switch_company_menu.xml @@ -0,0 +1,24 @@ + + + + + + o_switch_company_menu d-none d-md-block {{ user.activeCompanies.length > 1 ? 'o_company_context_highlighted' : '' }} + {{ user.activeCompanies.length > 1 ? '--o-company-context-highlight-bg: ' + highlightColor + '; --o-company-context-highlight-color: ' + highlightTextColor + ';' : '' }} + + + + + + + + diff --git a/web_company_context_highlight/static/tests/tours/web_company_context_highlight_tour.esm.js b/web_company_context_highlight/static/tests/tours/web_company_context_highlight_tour.esm.js new file mode 100644 index 00000000000..ff51140e6f3 --- /dev/null +++ b/web_company_context_highlight/static/tests/tours/web_company_context_highlight_tour.esm.js @@ -0,0 +1,83 @@ +/** + * Copyright 2026 Acsone + * @author Pierre Verkest + * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ + +import {registry} from "@web/core/registry"; + +registry.category("web_tour.tours").add("web_company_context_highlight_tour", { + steps: () => [ + // 1. Check absence of desktop building icon on the initial page load, and click switcher button + { + trigger: + ".o_switch_company_menu:not(.o_company_context_highlighted) button", + run: function (actions) { + const buildingIcon = document.querySelector( + ".o_switch_company_menu .fa-building-o.d-lg-inline-block" + ); + if (buildingIcon) { + throw new Error( + "fa-building desktop icon should not be present when only one company is active." + ); + } + actions.click(); + }, + }, + // 2. Select Company B checkbox to enable multi-company context + { + trigger: + ".o_switch_company_item:contains('Company B') div[role='menuitemcheckbox']", + run: "click", + }, + // 3. Click the confirm button to apply the change (causes reload) + { + trigger: + ".o_switch_company_menu_buttons button.btn-primary:contains('Confirm')", + run: "click", + expectUnloadPage: true, + }, + // 4. After reload, wait for the switcher to be highlighted, then check that the desktop building icon is present, and click to open the dropdown + { + trigger: ".o_switch_company_menu.o_company_context_highlighted button", + run: function (actions) { + const buildingIcon = document.querySelector( + ".o_switch_company_menu .fa-building-o.d-lg-inline-block" + ); + if (!buildingIcon) { + throw new Error( + "fa-building desktop icon should be present when multiple companies are active." + ); + } + actions.click(); + }, + }, + // 5. Deselect Company B + { + trigger: + ".o_switch_company_item:contains('Company B') div[role='menuitemcheckbox']", + run: "click", + }, + // 6. Click the confirm button again (causes reload) + { + trigger: + ".o_switch_company_menu_buttons button.btn-primary:contains('Confirm')", + run: "click", + expectUnloadPage: true, + }, + // 7. Verify we are back to single company, NOT highlighted, and desktop building icon is gone + { + trigger: + ".o_switch_company_menu:not(.o_company_context_highlighted) button", + run: function () { + const buildingIcon = document.querySelector( + ".o_switch_company_menu .fa-building-o.d-lg-inline-block" + ); + if (buildingIcon) { + throw new Error( + "fa-building desktop icon should not be present when returning to single company." + ); + } + }, + }, + ], +}); diff --git a/web_company_context_highlight/tests/__init__.py b/web_company_context_highlight/tests/__init__.py new file mode 100644 index 00000000000..ef8b112671b --- /dev/null +++ b/web_company_context_highlight/tests/__init__.py @@ -0,0 +1,3 @@ +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from . import test_tour diff --git a/web_company_context_highlight/tests/test_tour.py b/web_company_context_highlight/tests/test_tour.py new file mode 100644 index 00000000000..2af2e96c2d8 --- /dev/null +++ b/web_company_context_highlight/tests/test_tour.py @@ -0,0 +1,21 @@ +# Copyright 2026 Acsone +# @author Pierre Verkest +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo.tests.common import HttpCase, tagged + + +@tagged("post_install", "-at_install") +class TestWebCompanyContextHighlight(HttpCase): + def test_company_context_highlight_tour(self): + admin_user = self.env.ref("base.user_admin") + company_b = self.env["res.company"].create({"name": "Company B"}) + + admin_user.write( + { + "company_ids": [(4, company_b.id)], + } + ) + + # Launch the single interactive tour + self.start_tour("/odoo", "web_company_context_highlight_tour", login="admin") diff --git a/web_company_context_highlight/views/res_config_settings_views.xml b/web_company_context_highlight/views/res_config_settings_views.xml new file mode 100644 index 00000000000..6d74016677d --- /dev/null +++ b/web_company_context_highlight/views/res_config_settings_views.xml @@ -0,0 +1,52 @@ + + + + + res.config.settings.view.form.inherit.web_company_context_highlight + res.config.settings + + + + +
+
+
+
+
+
+
+
+
+
+