From 447c82e90c55e4520eecc7c7da0c8ca69b337943 Mon Sep 17 00:00:00 2001 From: hugues de keyzer Date: Tue, 2 Jul 2024 16:14:12 +0200 Subject: [PATCH] [ADD] new module web_widget_many2one_colored --- .../odoo/addons/web_widget_many2one_colored | 1 + setup/web_widget_many2one_colored/setup.py | 6 + web_widget_many2one_colored/README.rst | 121 +++++ web_widget_many2one_colored/__init__.py | 3 + web_widget_many2one_colored/__manifest__.py | 21 + .../readme/CONTRIBUTORS.rst | 3 + .../readme/CREDITS.rst | 2 + .../readme/DESCRIPTION.rst | 1 + .../readme/ROADMAP.rst | 2 + web_widget_many2one_colored/readme/USAGE.rst | 27 + .../static/description/index.html | 464 ++++++++++++++++++ .../static/src/autocomplete_colored.esm.js | 20 + .../static/src/autocomplete_colored.xml | 17 + .../src/autocomplete_colored_option.xml | 10 + .../static/src/many2one_colored_field.esm.js | 86 ++++ .../static/src/many2one_colored_field.xml | 24 + .../src/many2x_autocomplete_colored.esm.js | 40 ++ .../src/many2x_autocomplete_colored.xml | 33 ++ .../src/web_widget_many2one_colored.scss | 12 + 19 files changed, 893 insertions(+) create mode 120000 setup/web_widget_many2one_colored/odoo/addons/web_widget_many2one_colored create mode 100644 setup/web_widget_many2one_colored/setup.py create mode 100644 web_widget_many2one_colored/README.rst create mode 100644 web_widget_many2one_colored/__init__.py create mode 100644 web_widget_many2one_colored/__manifest__.py create mode 100644 web_widget_many2one_colored/readme/CONTRIBUTORS.rst create mode 100644 web_widget_many2one_colored/readme/CREDITS.rst create mode 100644 web_widget_many2one_colored/readme/DESCRIPTION.rst create mode 100644 web_widget_many2one_colored/readme/ROADMAP.rst create mode 100644 web_widget_many2one_colored/readme/USAGE.rst create mode 100644 web_widget_many2one_colored/static/description/index.html create mode 100644 web_widget_many2one_colored/static/src/autocomplete_colored.esm.js create mode 100644 web_widget_many2one_colored/static/src/autocomplete_colored.xml create mode 100644 web_widget_many2one_colored/static/src/autocomplete_colored_option.xml create mode 100644 web_widget_many2one_colored/static/src/many2one_colored_field.esm.js create mode 100644 web_widget_many2one_colored/static/src/many2one_colored_field.xml create mode 100644 web_widget_many2one_colored/static/src/many2x_autocomplete_colored.esm.js create mode 100644 web_widget_many2one_colored/static/src/many2x_autocomplete_colored.xml create mode 100644 web_widget_many2one_colored/static/src/web_widget_many2one_colored.scss diff --git a/setup/web_widget_many2one_colored/odoo/addons/web_widget_many2one_colored b/setup/web_widget_many2one_colored/odoo/addons/web_widget_many2one_colored new file mode 120000 index 000000000000..13e766722d3c --- /dev/null +++ b/setup/web_widget_many2one_colored/odoo/addons/web_widget_many2one_colored @@ -0,0 +1 @@ +../../../../web_widget_many2one_colored \ No newline at end of file diff --git a/setup/web_widget_many2one_colored/setup.py b/setup/web_widget_many2one_colored/setup.py new file mode 100644 index 000000000000..28c57bb64031 --- /dev/null +++ b/setup/web_widget_many2one_colored/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/web_widget_many2one_colored/README.rst b/web_widget_many2one_colored/README.rst new file mode 100644 index 000000000000..5ca18f91c234 --- /dev/null +++ b/web_widget_many2one_colored/README.rst @@ -0,0 +1,121 @@ +============================= +Colored Many2one field widget +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:6c665bb94dac0f660a9ae65679c32b7c2ea4450ba8d507bd8a0faae5a143abf6 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github + :target: https://github.com/OCA/web/tree/16.0/web_widget_many2one_colored + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-16-0/web-16-0-web_widget_many2one_colored + :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=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Display ``Many2one`` fields using a color field of their model. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To use this widget, use the ``widget`` attribute on a ``Many2one`` field: + +.. code-block:: XML + + + +The ``no_open`` option is required for the field to appear in color, otherwise +it will be a hyperlink allowing to open the corresponding record, and thus +styled as a hyperlink. + +By default, the widget uses a field named ``color`` of the target model to +determine the color. It should be an ``Integer`` field with values from 0 to +12 (corresponding to the colors available in the ``color_picker`` field +widget). To use another field of the target model, use the ``color_field`` +option: + +.. code-block:: XML + + + +Known issues / Roadmap +====================== + +* In mobile mode (``env.isSmall`` is true), the view displaying the available + choices does not display the records with their corresponding color. + +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 +~~~~~~~ + +* Coop IT Easy SC + +Contributors +~~~~~~~~~~~~ + +* `Coop IT Easy SC `_: + + * hugues de keyzer + +Other credits +~~~~~~~~~~~~~ + +The development of this module has been funded by `iMio sc +`_. + +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. + +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_widget_many2one_colored/__init__.py b/web_widget_many2one_colored/__init__.py new file mode 100644 index 000000000000..c48d182bbfa0 --- /dev/null +++ b/web_widget_many2one_colored/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/web_widget_many2one_colored/__manifest__.py b/web_widget_many2one_colored/__manifest__.py new file mode 100644 index 000000000000..e0187dff47cd --- /dev/null +++ b/web_widget_many2one_colored/__manifest__.py @@ -0,0 +1,21 @@ +# SPDX-FileCopyrightText: 2024 Coop IT Easy SC +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +{ + "name": "Colored Many2one field widget", + "summary": "Display Many2one fields using a color field of their model", + "version": "16.0.1.0.0", + "category": "Web", + "website": "https://github.com/OCA/web", + "author": "Coop IT Easy SC, Odoo Community Association (OCA)", + "license": "AGPL-3", + "depends": [ + "web", + ], + "assets": { + "web.assets_backend": [ + "web_widget_many2one_colored/static/src/*", + ], + }, +} diff --git a/web_widget_many2one_colored/readme/CONTRIBUTORS.rst b/web_widget_many2one_colored/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000000..eb7c015bfe76 --- /dev/null +++ b/web_widget_many2one_colored/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Coop IT Easy SC `_: + + * hugues de keyzer diff --git a/web_widget_many2one_colored/readme/CREDITS.rst b/web_widget_many2one_colored/readme/CREDITS.rst new file mode 100644 index 000000000000..c796c7a2e218 --- /dev/null +++ b/web_widget_many2one_colored/readme/CREDITS.rst @@ -0,0 +1,2 @@ +The development of this module has been funded by `iMio sc +`_. diff --git a/web_widget_many2one_colored/readme/DESCRIPTION.rst b/web_widget_many2one_colored/readme/DESCRIPTION.rst new file mode 100644 index 000000000000..5f9909a40e65 --- /dev/null +++ b/web_widget_many2one_colored/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Display ``Many2one`` fields using a color field of their model. diff --git a/web_widget_many2one_colored/readme/ROADMAP.rst b/web_widget_many2one_colored/readme/ROADMAP.rst new file mode 100644 index 000000000000..fd0969b68a0e --- /dev/null +++ b/web_widget_many2one_colored/readme/ROADMAP.rst @@ -0,0 +1,2 @@ +* In mobile mode (``env.isSmall`` is true), the view displaying the available + choices does not display the records with their corresponding color. diff --git a/web_widget_many2one_colored/readme/USAGE.rst b/web_widget_many2one_colored/readme/USAGE.rst new file mode 100644 index 000000000000..29899f1f01aa --- /dev/null +++ b/web_widget_many2one_colored/readme/USAGE.rst @@ -0,0 +1,27 @@ +To use this widget, use the ``widget`` attribute on a ``Many2one`` field: + +.. code-block:: XML + + + +The ``no_open`` option is required for the field to appear in color, otherwise +it will be a hyperlink allowing to open the corresponding record, and thus +styled as a hyperlink. + +By default, the widget uses a field named ``color`` of the target model to +determine the color. It should be an ``Integer`` field with values from 0 to +12 (corresponding to the colors available in the ``color_picker`` field +widget). To use another field of the target model, use the ``color_field`` +option: + +.. code-block:: XML + + diff --git a/web_widget_many2one_colored/static/description/index.html b/web_widget_many2one_colored/static/description/index.html new file mode 100644 index 000000000000..4cabb3a94567 --- /dev/null +++ b/web_widget_many2one_colored/static/description/index.html @@ -0,0 +1,464 @@ + + + + + + +Colored Many2one field widget + + + +
+

Colored Many2one field widget

+ + +

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

+

Display Many2one fields using a color field of their model.

+

Table of contents

+ +
+

Usage

+

To use this widget, use the widget attribute on a Many2one field:

+
+<field
+    name="type_id"
+    widget="many2one_colored"
+    options="{'no_open': True}"
+/>
+
+

The no_open option is required for the field to appear in color, otherwise +it will be a hyperlink allowing to open the corresponding record, and thus +styled as a hyperlink.

+

By default, the widget uses a field named color of the target model to +determine the color. It should be an Integer field with values from 0 to +12 (corresponding to the colors available in the color_picker field +widget). To use another field of the target model, use the color_field +option:

+
+<field
+    name="type_id"
+    widget="many2one_colored"
+    options="{'no_open': True, 'color_field': 'display_color'}"
+/>
+
+
+
+

Known issues / Roadmap

+
    +
  • In mobile mode (env.isSmall is true), the view displaying the available +choices does not display the records with their corresponding color.
  • +
+
+
+

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

+
    +
  • Coop IT Easy SC
  • +
+
+
+

Contributors

+ +
+
+

Other credits

+

The development of this module has been funded by iMio sc.

+
+
+

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.

+

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_widget_many2one_colored/static/src/autocomplete_colored.esm.js b/web_widget_many2one_colored/static/src/autocomplete_colored.esm.js new file mode 100644 index 000000000000..762258715618 --- /dev/null +++ b/web_widget_many2one_colored/static/src/autocomplete_colored.esm.js @@ -0,0 +1,20 @@ +/** @odoo-module */ + +import {AutoComplete} from "@web/core/autocomplete/autocomplete"; + +const NO_COLOR = 0; + +export class AutoCompleteColored extends AutoComplete { + async onInput() { + // Unset color as soon as the value is edited, as it does not + // correspond to a selected choice. + this.props.color = NO_COLOR; + return super.onInput(); + } +} + +AutoCompleteColored.template = "web_widget_many2one_colored.AutoCompleteColored"; +AutoCompleteColored.props = { + ...AutoComplete.props, + color: {type: Number}, +}; diff --git a/web_widget_many2one_colored/static/src/autocomplete_colored.xml b/web_widget_many2one_colored/static/src/autocomplete_colored.xml new file mode 100644 index 000000000000..21a7e036bc40 --- /dev/null +++ b/web_widget_many2one_colored/static/src/autocomplete_colored.xml @@ -0,0 +1,17 @@ + + + + + + o-autocomplete--input o_input o_many2one_colored_item_color_{{ props.color }} + + + + diff --git a/web_widget_many2one_colored/static/src/autocomplete_colored_option.xml b/web_widget_many2one_colored/static/src/autocomplete_colored_option.xml new file mode 100644 index 000000000000..112e18e8f755 --- /dev/null +++ b/web_widget_many2one_colored/static/src/autocomplete_colored_option.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/web_widget_many2one_colored/static/src/many2one_colored_field.esm.js b/web_widget_many2one_colored/static/src/many2one_colored_field.esm.js new file mode 100644 index 000000000000..6a01467c3e18 --- /dev/null +++ b/web_widget_many2one_colored/static/src/many2one_colored_field.esm.js @@ -0,0 +1,86 @@ +/** @odoo-module */ + +import {onWillStart, onWillUpdateProps} from "@odoo/owl"; + +import {Many2OneField} from "@web/views/fields/many2one/many2one_field"; +import {Many2XAutocompleteColored} from "./many2x_autocomplete_colored.esm"; +import {registry} from "@web/core/registry"; +import {useService} from "@web/core/utils/hooks"; + +const DEFAULT_COLOR_FIELD = "color"; +const COLOR_FIELD_OPTION_NAME = "color_field"; +const NO_COLOR = 0; + +function resIDFromProps(props) { + if (!props.value) { + return null; + } + return props.value[0]; +} + +export class Many2OneColoredField extends Many2OneField { + setup() { + super.setup(); + this.orm = useService("orm"); + this._colorField = this.props.colorField || DEFAULT_COLOR_FIELD; + this._color = NO_COLOR; + this._currentID = null; + + onWillStart(() => { + return this.loadColor(resIDFromProps(this.props)); + }); + + onWillUpdateProps((nextProps) => { + return this.loadColor(resIDFromProps(nextProps)); + }); + } + + get Many2XAutocompleteProps() { + const props = super.Many2XAutocompleteProps; + Object.assign(props, { + colorField: this._colorField, + color: this._color, + }); + return props; + } + + async loadColor(resID) { + if (resID === this._currentID) { + return; + } + this._currentID = resID; + if (resID === null) { + this._color = NO_COLOR; + return; + } + const records = await this.orm.read(this.relation, [resID], [this._colorField]); + this._color = records[0][this._colorField]; + } + + get color() { + return this._color; + } +} + +Many2OneColoredField.template = "web_widget_many2one_colored.Many2OneColoredField"; +Many2OneColoredField.components = { + Many2XAutocompleteColored, +}; +// This needs to be dynamic, because other modules like web_m2x_options modify +// Many2OneField.props after this. +Object.defineProperty(Many2OneColoredField, "props", { + get: () => { + return { + ...Many2OneField.props, + colorField: {type: String, optional: true}, + }; + }, +}); +Many2OneColoredField.extractProps = ({attrs, field}) => { + return { + ...Many2OneField.extractProps({attrs, field}), + colorField: attrs.options[COLOR_FIELD_OPTION_NAME], + }; +}; + +registry.category("fields").add("many2one_colored", Many2OneColoredField); diff --git a/web_widget_many2one_colored/static/src/many2one_colored_field.xml b/web_widget_many2one_colored/static/src/many2one_colored_field.xml new file mode 100644 index 000000000000..2186a76d4385 --- /dev/null +++ b/web_widget_many2one_colored/static/src/many2one_colored_field.xml @@ -0,0 +1,24 @@ + + + + + + o_many2one_colored_item_color_{{ color }} + + + + + + + + diff --git a/web_widget_many2one_colored/static/src/many2x_autocomplete_colored.esm.js b/web_widget_many2one_colored/static/src/many2x_autocomplete_colored.esm.js new file mode 100644 index 000000000000..a4c718aa905d --- /dev/null +++ b/web_widget_many2one_colored/static/src/many2x_autocomplete_colored.esm.js @@ -0,0 +1,40 @@ +/** @odoo-module */ + +import {AutoCompleteColored} from "./autocomplete_colored.esm"; +import {Many2XAutocomplete} from "@web/views/fields/relational_utils"; + +export class Many2XAutocompleteColored extends Many2XAutocomplete { + get optionsSource() { + return { + ...super.optionsSource, + optionTemplate: "web_widget_many2one_colored.AutoCompleteColoredOption", + }; + } + + async loadOptionsSource(request) { + const result = await super.loadOptionsSource(request); + const ids = []; + const idToIndex = {}; + for (let i = 0; i < result.length; ++i) { + const option = result[i]; + if (option.value === undefined) { + break; + } + ids.push(option.value); + idToIndex[option.value] = i; + } + const records = await this.orm.read(this.props.resModel, ids, [ + this.props.colorField, + ]); + for (const record of records) { + result[idToIndex[record.id]].color = record[this.props.colorField]; + } + return result; + } +} + +Many2XAutocompleteColored.template = + "web_widget_many2one_colored.Many2XAutocompleteColored"; +Many2XAutocompleteColored.components = { + AutoCompleteColored, +}; diff --git a/web_widget_many2one_colored/static/src/many2x_autocomplete_colored.xml b/web_widget_many2one_colored/static/src/many2x_autocomplete_colored.xml new file mode 100644 index 000000000000..c91d97bd630f --- /dev/null +++ b/web_widget_many2one_colored/static/src/many2x_autocomplete_colored.xml @@ -0,0 +1,33 @@ + + + + + + o_input o_many2one_colored_item_color_{{ props.color }} + + + + + + + + diff --git a/web_widget_many2one_colored/static/src/web_widget_many2one_colored.scss b/web_widget_many2one_colored/static/src/web_widget_many2one_colored.scss new file mode 100644 index 000000000000..f0e9e1acf759 --- /dev/null +++ b/web_widget_many2one_colored/static/src/web_widget_many2one_colored.scss @@ -0,0 +1,12 @@ +// set all the colors but the "no-color" one +@for $size from 2 through length($o-colors) { + .o_many2one_colored_item_color_#{$size - 1}, + .o_field_widget input.o_many2one_colored_item_color_#{$size - 1} { + color: nth($o-colors, $size); + } +} + +// this is the default style when no color is set. defining this is not +// needed, but it could be confusing otherwise. +.o_many2one_colored_item_color_0 { +}