diff --git a/web_edit_xmlid/README.rst b/web_edit_xmlid/README.rst new file mode 100644 index 000000000000..075138856b25 --- /dev/null +++ b/web_edit_xmlid/README.rst @@ -0,0 +1,129 @@ +=============== +Web Edit XML ID +=============== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:ddf37c3c74bc3c13d6d5c0d380b67aa12ee74662494bdd24e002cde8c9e065b1 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png + :target: https://odoo-community.org/page/development-status + :alt: Production/Stable +.. |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/18.0/web_edit_xmlid + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-18-0/web-18-0-web_edit_xmlid + :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=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module override the default method used to read current record +metadata in order to provide two new actions: Create or Edit XML ID. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To use this module, you need to: + +1. Enable the debug mode to show the Developer menu. + +2. Click on View Metadata to open the built-in metadata viewer. + +3. If the record doesn't have an XML ID, the Create button will call the + same built-in method used during a row export to generate a unique + ID. + + *Create a new unique XML ID* + + |image| + + *XML ID created* + + |image1| + +4. If the record is already linked to an XML ID, an Edit button will + open a Form to update it. + + *Edit an existing XML ID* + + |image2| + + *XML ID editable form view* + + |image3| + + *XML ID edited* + + |image4| + +.. |image| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_edit_xmlid/static/img/xmlid-create.jpg +.. |image1| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_edit_xmlid/static/img/xmlid-created.jpg +.. |image2| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_edit_xmlid/static/img/xmlid-edit.jpg +.. |image3| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_edit_xmlid/static/img/xmlid-editing.jpg +.. |image4| image:: https://raw.githubusercontent.com/OCA/web/18.0/web_edit_xmlid/static/img/xmlid-edited.jpg + +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 +------- + +* DEC + +Contributors +------------ + +- `DEC `__: + + - Yann Papouin + +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-ypapouin| image:: https://github.com/ypapouin.png?size=40px + :target: https://github.com/ypapouin + :alt: ypapouin + +Current `maintainer `__: + +|maintainer-ypapouin| + +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_edit_xmlid/__init__.py b/web_edit_xmlid/__init__.py new file mode 100755 index 000000000000..0650744f6bc6 --- /dev/null +++ b/web_edit_xmlid/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/web_edit_xmlid/__manifest__.py b/web_edit_xmlid/__manifest__.py new file mode 100755 index 000000000000..168e703dfc31 --- /dev/null +++ b/web_edit_xmlid/__manifest__.py @@ -0,0 +1,22 @@ +{ + "name": "Web Edit XML ID", + "version": "18.0.1.0.0", + "license": "AGPL-3", + "category": "Base", + "website": "https://github.com/OCA/web", + "development_status": "Production/Stable", + "author": "DEC, Odoo Community Association (OCA)", + "maintainers": ["ypapouin"], + "depends": [ + "web", + ], + "data": [], + "qweb": [], + "assets": { + "web.assets_backend": [ + "web_edit_xmlid/static/src/core/**/*", + "web_edit_xmlid/static/src/views/**/*", + ], + }, + "installable": True, +} diff --git a/web_edit_xmlid/i18n/fr.po b/web_edit_xmlid/i18n/fr.po new file mode 100644 index 000000000000..8e8312883fe4 --- /dev/null +++ b/web_edit_xmlid/i18n/fr.po @@ -0,0 +1,58 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_edit_xmlid +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-05-31 07:11+0000\n" +"PO-Revision-Date: 2021-05-31 09:12+0200\n" +"Last-Translator: Yann Papouin \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 2.3\n" + +#. module: web_edit_xmlid +#: model:ir.model,name:web_edit_xmlid.model_base +msgid "Base" +msgstr "Base" + +#. module: web_edit_xmlid +#. openerp-web +#: code:addons/web_edit_xmlid/static/src/xml/base.xml:10 +#, python-format +msgid "Create" +msgstr "Créer" + +#. module: web_edit_xmlid +#. openerp-web +#: code:addons/web_edit_xmlid/static/src/xml/base.xml:7 +#, python-format +msgid "Edit" +msgstr "Modifier" + +#. module: web_edit_xmlid +#. openerp-web +#: code:addons/web_edit_xmlid/static/src/js/tools/debug_manager.js:81 +#, python-format +msgid "Edit XML ID" +msgstr "Modification du XML ID" + +#. module: web_edit_xmlid +#. openerp-web +#: code:addons/web_edit_xmlid/static/src/js/tools/debug_manager.js:41 +#, python-format +msgid "Metadata (%s)" +msgstr "Métadonnées (%s)" + +#. module: web_edit_xmlid +#. openerp-web +#: code:addons/web_edit_xmlid/static/src/js/tools/debug_manager.js:25 +#, python-format +msgid "No metadata available" +msgstr "Pas de méta-données disponibles" diff --git a/web_edit_xmlid/i18n/web_edit_xmlid.po b/web_edit_xmlid/i18n/web_edit_xmlid.po new file mode 100644 index 000000000000..4a8262d17a2e --- /dev/null +++ b/web_edit_xmlid/i18n/web_edit_xmlid.po @@ -0,0 +1,57 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_edit_xmlid +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-05-31 07:11+0000\n" +"PO-Revision-Date: 2021-05-31 07:11+0000\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_edit_xmlid +#: model:ir.model,name:web_edit_xmlid.model_base +msgid "Base" +msgstr "" + +#. module: web_edit_xmlid +#. openerp-web +#: code:addons/web_edit_xmlid/static/src/xml/base.xml:10 +#, python-format +msgid "Create" +msgstr "" + +#. module: web_edit_xmlid +#. openerp-web +#: code:addons/web_edit_xmlid/static/src/xml/base.xml:7 +#, python-format +msgid "Edit" +msgstr "" + +#. module: web_edit_xmlid +#. openerp-web +#: code:addons/web_edit_xmlid/static/src/js/tools/debug_manager.js:81 +#, python-format +msgid "Edit XML ID" +msgstr "" + +#. module: web_edit_xmlid +#. openerp-web +#: code:addons/web_edit_xmlid/static/src/js/tools/debug_manager.js:41 +#, python-format +msgid "Metadata (%s)" +msgstr "" + +#. module: web_edit_xmlid +#. openerp-web +#: code:addons/web_edit_xmlid/static/src/js/tools/debug_manager.js:25 +#, python-format +msgid "No metadata available" +msgstr "" + diff --git a/web_edit_xmlid/models/__init__.py b/web_edit_xmlid/models/__init__.py new file mode 100755 index 000000000000..0650744f6bc6 --- /dev/null +++ b/web_edit_xmlid/models/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/web_edit_xmlid/models/models.py b/web_edit_xmlid/models/models.py new file mode 100644 index 000000000000..57868af0d070 --- /dev/null +++ b/web_edit_xmlid/models/models.py @@ -0,0 +1,24 @@ +from odoo import models + + +class BaseModel(models.BaseModel): + _inherit = "base" + + def ensure_xml_id(self, skip=False): + """Public version of `__ensure_xml_id` used by DebugManager. + Since `__ensure_xml_id` use raw SQL queries to create data + standard ORM fields (`create_uid`, `write_uid`) are not filled correctly. + """ + res = self.__ensure_xml_id(skip) + xids = [] + for _record, xid in res: + xids.append(self.env["ir.model.data"].xmlid_lookup(xid)[0]) + # To avoid having our record manually linked with a XML_ID to be + # deleted when the module that owns this record will be updated, we + # set `noupdate` to True. + # This is done only once since `write_uid` will be set there. + xml_ids = self.env["ir.model.data"].search( + [("id", "in", xids), ("write_uid", "=", False)] + ) + xml_ids.write({"noupdate": True}) + return res diff --git a/web_edit_xmlid/pyproject.toml b/web_edit_xmlid/pyproject.toml new file mode 100644 index 000000000000..4231d0cccb3d --- /dev/null +++ b/web_edit_xmlid/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/web_edit_xmlid/readme/CONTRIBUTORS.md b/web_edit_xmlid/readme/CONTRIBUTORS.md new file mode 100644 index 000000000000..40c234677eca --- /dev/null +++ b/web_edit_xmlid/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- [DEC](https://www.decgroupe.com): + - Yann Papouin \ diff --git a/web_edit_xmlid/readme/DESCRIPTION.md b/web_edit_xmlid/readme/DESCRIPTION.md new file mode 100644 index 000000000000..e85d69369c73 --- /dev/null +++ b/web_edit_xmlid/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This module override the default method used to read current record +metadata in order to provide an Edit XML ID action. diff --git a/web_edit_xmlid/readme/USAGE.md b/web_edit_xmlid/readme/USAGE.md new file mode 100644 index 000000000000..1b4b524a2539 --- /dev/null +++ b/web_edit_xmlid/readme/USAGE.md @@ -0,0 +1,29 @@ +To use this module, you need to: + +1. Enable the debug mode to show the Developer menu. + +2. Click on `Metadata` to open the built-in metadata viewer. + +3. If the record doesn't have an XML ID, the `(create)` button will open + the built-in dialog to edit it. + + *Create a new XML ID* + + ![image](../static/img/xmlid-create.jpg) + + ![image](../static/img/xmlid-creating.jpg) + +4. If the record is already linked to one (and only one) XML ID, an `(edit)` + button will open a Form to update it. + + *Edit an existing XML ID* + + ![image](../static/img/xmlid-edit.jpg) + + *XML ID editable form view* + + ![image](../static/img/xmlid-editing.jpg) + + *XML ID edited* + + ![image](../static/img/xmlid-edited.jpg) diff --git a/web_edit_xmlid/static/description/icon.png b/web_edit_xmlid/static/description/icon.png new file mode 100644 index 000000000000..4c6f8717cdd4 Binary files /dev/null and b/web_edit_xmlid/static/description/icon.png differ diff --git a/web_edit_xmlid/static/description/icon.svg b/web_edit_xmlid/static/description/icon.svg new file mode 100755 index 000000000000..5667a77de3ba --- /dev/null +++ b/web_edit_xmlid/static/description/icon.svg @@ -0,0 +1,713 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + </> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web_edit_xmlid/static/description/index.html b/web_edit_xmlid/static/description/index.html new file mode 100644 index 000000000000..77f9b4549b3f --- /dev/null +++ b/web_edit_xmlid/static/description/index.html @@ -0,0 +1,457 @@ + + + + + +Web Edit XML ID + + + +
+

Web Edit XML ID

+ + +

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

+

This module override the default method used to read current record +metadata in order to provide two new actions: Create or Edit XML ID.

+

Table of contents

+ +
+

Usage

+

To use this module, you need to:

+
    +
  1. Enable the debug mode to show the Developer menu.

    +
  2. +
  3. Click on View Metadata to open the built-in metadata viewer.

    +
  4. +
  5. If the record doesn’t have an XML ID, the Create button will call the +same built-in method used during a row export to generate a unique +ID.

    +

    Create a new unique XML ID

    +

    image

    +

    XML ID created

    +

    image1

    +
  6. +
  7. If the record is already linked to an XML ID, an Edit button will +open a Form to update it.

    +

    Edit an existing XML ID

    +

    image2

    +

    XML ID editable form view

    +

    image3

    +

    XML ID edited

    +

    image4

    +
  8. +
+
+
+

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

+
    +
  • DEC
  • +
+
+
+

Contributors

+ +
+
+

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:

+

ypapouin

+

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_edit_xmlid/static/img/xmlid-create.jpg b/web_edit_xmlid/static/img/xmlid-create.jpg new file mode 100644 index 000000000000..dcb736ff0040 Binary files /dev/null and b/web_edit_xmlid/static/img/xmlid-create.jpg differ diff --git a/web_edit_xmlid/static/img/xmlid-creating.jpg b/web_edit_xmlid/static/img/xmlid-creating.jpg new file mode 100644 index 000000000000..f318cf0584f4 Binary files /dev/null and b/web_edit_xmlid/static/img/xmlid-creating.jpg differ diff --git a/web_edit_xmlid/static/img/xmlid-edit.jpg b/web_edit_xmlid/static/img/xmlid-edit.jpg new file mode 100644 index 000000000000..6379a6dbd7de Binary files /dev/null and b/web_edit_xmlid/static/img/xmlid-edit.jpg differ diff --git a/web_edit_xmlid/static/img/xmlid-edited.jpg b/web_edit_xmlid/static/img/xmlid-edited.jpg new file mode 100644 index 000000000000..cba912be9e2e Binary files /dev/null and b/web_edit_xmlid/static/img/xmlid-edited.jpg differ diff --git a/web_edit_xmlid/static/img/xmlid-editing.jpg b/web_edit_xmlid/static/img/xmlid-editing.jpg new file mode 100644 index 000000000000..c51bea59aa1c Binary files /dev/null and b/web_edit_xmlid/static/img/xmlid-editing.jpg differ diff --git a/web_edit_xmlid/static/src/core/debug/debug_menu_items.xml b/web_edit_xmlid/static/src/core/debug/debug_menu_items.xml new file mode 100644 index 000000000000..37955f44e0ae --- /dev/null +++ b/web_edit_xmlid/static/src/core/debug/debug_menu_items.xml @@ -0,0 +1,12 @@ + + + + + + + (edit) + + + + + diff --git a/web_edit_xmlid/static/src/views/debug_items.js b/web_edit_xmlid/static/src/views/debug_items.js new file mode 100644 index 000000000000..795ca7fdb9a5 --- /dev/null +++ b/web_edit_xmlid/static/src/views/debug_items.js @@ -0,0 +1,22 @@ +import { patch } from "@web/core/utils/patch"; +import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog"; +import { GetMetadataDialog } from "@web/views/debug_items"; + +patch(GetMetadataDialog.prototype, { + async onClickEditXmlid() { + const model_data_id = await this.orm.call("ir.model.data", "search", [], + { + domain: [ + ["model", "=", this.props.resModel], + ["res_id", "=", this.state.id], + ], + limit: 1, + }, + ); + this.dialogService.add(FormViewDialog, { + onRecordSaved: () => this.loadMetadata(), + resModel: "ir.model.data", + resId: model_data_id[0], + }); + } +}); diff --git a/web_tree_dynamic_colored_field/README.rst b/web_tree_dynamic_colored_field/README.rst index 13c1e46e9200..0eeb72b35776 100644 --- a/web_tree_dynamic_colored_field/README.rst +++ b/web_tree_dynamic_colored_field/README.rst @@ -28,16 +28,25 @@ Colorize field in tree views |badge1| |badge2| |badge3| |badge4| |badge5| -This module aims to add support for dynamically coloring fields in tree +This module aims to add support for dynamically coloring fields in list view according to data in the record. Features -------- - Add attribute ``bg_color`` on field's ``options`` to color background - of a cell in tree view + of a cell in list view - Add attribute ``fg_color`` on field's ``options`` to change text color - of a cell in tree view + of a cell in list view +- Add attribute ``bg_color_field`` on list's ``colors`` to change + background color of the entire row in list view (\*) +- Add attribute ``fg_color_field`` on list's ``colors`` to change text + color of the entire row in list view (\*) + +(\*) This functionality only works for list defined in a form. Since +13.0, the ``colors`` attribute is no longer in the RelaxNG schema of the +list view, so we can't use it like before, but it looks like the RNG is +not checked for embedded list. **Table of contents** @@ -47,76 +56,79 @@ Features Usage ===== -- In the tree view declaration, put +Using view conditions +===================== + +- In the list view declaration, put ``options='{"bg_color": "red: customer==True"}`` attribute in the ``field`` tag: - :: + .. code:: xml ... - + ... ... - + ... - With this example, column which renders 'name' field will have its **background** colored in red on customer records. + With this example, column which renders 'name' field will have its + **background** colored in red on customer records. -- In the tree view declaration, put +- In the list view declaration, put ``options='{"fg_color": "white:customer == True"}'`` attribute in the ``field`` tag: - :: + .. code:: xml ... - + ... ... - + ... - With this example, column which renders 'name' field will have its **text** colored in white on customer records. + With this example, column which renders 'name' field will have its + **text** colored in white on customer records. - If you want to use more than one color, you can split the attributes using ';': -:: - - options='{"fg_color": "red:red_color == True; green:green_color == True"}' + :: -Example: + options='{"fg_color": "red:red_color == True; green:green_color == True"}' -.. code:: xml + .. code:: xml - ... - - - ... - - ... - - - ... + ... + + + ... + + ... + + + ... -- Can use strings too... In the tree view declaration, put +- Can use strings too... In the list view declaration, put ``options="{'fg_color': 'green:customer_state == \'success\''}"`` attribute in the ``field`` tag: - :: + .. code:: xml ... - + ... ... - + ... @@ -124,15 +136,33 @@ Example: the options doesn't follow the JSON format, the options string will be evaluated using py.eval()** +Using view fields +================= + +- In the list view declaration, put + ``options='{"bg_color": "my_color"}`` attribute in the ``field`` tag: + + .. code:: xml + + ... + + + ... + + + ... + + + ... + + With this example, the content of the field named ``my_color`` will be + used to populate the ``background-color`` CSS value. Use a compute + field to return whichever color you want depending on the other record + values. + Known issues / Roadmap ====================== -- Before version 13.0, this module had a feature allowing to change the - color of a line depending on a field, using a ``colors`` attribute - with the name of the field on the ```` element. Since 13.0, the - ``colors`` attribute is no longer in the RelaxNG schema of the tree - view, so we can't use it anymore. This feature has then been dropped, - but could be reimplement in another way. - Since version 17.0 coloring is written into ``style`` attribute of (td) element @@ -165,6 +195,7 @@ Contributors - Phuc Tran Thanh - Sylvain LE GAL - Jurgis Pralgauskis +- Yann Papouin Other credits ------------- diff --git a/web_tree_dynamic_colored_field/__manifest__.py b/web_tree_dynamic_colored_field/__manifest__.py index 8e798bd0f1b9..c9d559a71b6a 100644 --- a/web_tree_dynamic_colored_field/__manifest__.py +++ b/web_tree_dynamic_colored_field/__manifest__.py @@ -9,7 +9,11 @@ "author": "Camptocamp, Therp BV, Odoo Community Association (OCA)", "license": "AGPL-3", "website": "https://github.com/OCA/web", - "demo": ["demo/res_users.xml"], + "demo": [ + "demo/ir_config_parameter.xml", + "demo/res_users.xml", + "demo/res_groups.xml", + ], "installable": True, "assets": { "web.assets_backend": [ diff --git a/web_tree_dynamic_colored_field/demo/ir_config_parameter.xml b/web_tree_dynamic_colored_field/demo/ir_config_parameter.xml new file mode 100644 index 000000000000..b01ada997054 --- /dev/null +++ b/web_tree_dynamic_colored_field/demo/ir_config_parameter.xml @@ -0,0 +1,21 @@ + + + + ir.config_parameter + + + + { + "fg_color": "key", + "bg_color": "value", + } + + + { + "fg_color": "value", + "bg_color": "key", + } + + + + diff --git a/web_tree_dynamic_colored_field/demo/res_groups.xml b/web_tree_dynamic_colored_field/demo/res_groups.xml new file mode 100644 index 000000000000..a975203531a4 --- /dev/null +++ b/web_tree_dynamic_colored_field/demo/res_groups.xml @@ -0,0 +1,13 @@ + + + + res.groups.form + res.groups + + + + bg_color_field: name + + + + diff --git a/web_tree_dynamic_colored_field/demo/res_users.xml b/web_tree_dynamic_colored_field/demo/res_users.xml index c2f004e70dc9..2bc0511ff4b2 100644 --- a/web_tree_dynamic_colored_field/demo/res_users.xml +++ b/web_tree_dynamic_colored_field/demo/res_users.xml @@ -6,15 +6,15 @@ { - "bg_color": "#9e1635: login_date == False", - "fg_color": "white: login_date == False" - } + "bg_color": "#9e1635: login_date == False", + "fg_color": "white: login_date == False" + } { - "bg_color": "blue; #653b5b: login == 'admin'", - "fg_color": "white" - } + "bg_color": "blue; #653b5b: login == 'admin'", + "fg_color": "white" + } diff --git a/web_tree_dynamic_colored_field/readme/CONTRIBUTORS.md b/web_tree_dynamic_colored_field/readme/CONTRIBUTORS.md index 36093db6e17f..9d1135e376df 100644 --- a/web_tree_dynamic_colored_field/readme/CONTRIBUTORS.md +++ b/web_tree_dynamic_colored_field/readme/CONTRIBUTORS.md @@ -5,3 +5,4 @@ - Phuc Tran Thanh \<\> - Sylvain LE GAL \<\> - Jurgis Pralgauskis \<\> +- Yann Papouin \<\> diff --git a/web_tree_dynamic_colored_field/readme/DESCRIPTION.md b/web_tree_dynamic_colored_field/readme/DESCRIPTION.md index f1c8a74a115e..8207e75681b2 100644 --- a/web_tree_dynamic_colored_field/readme/DESCRIPTION.md +++ b/web_tree_dynamic_colored_field/readme/DESCRIPTION.md @@ -1,9 +1,31 @@ -This module aims to add support for dynamically coloring fields in tree -view according to data in the record. +This module aims to add support for dynamically coloring fields in list view according +to data in the record. ## Features -- Add attribute `bg_color` on field's `options` to color background of a - cell in tree view -- Add attribute `fg_color` on field's `options` to change text color of - a cell in tree view +- Add attribute `bg_color` on field's `options` to color background of a cell in list + view +- Add attribute `fg_color` on field's `options` to change text color of a cell in list + view +- Add attribute `bg_color_field` on list's `colors` to change background color of the + entire row in list view (\*) +- Add attribute `fg_color_field` on list's `colors` to change text color of the entire + row in list view (\*) + +(\*) This functionality only works for a list defined in a form. (Since 13.0, the +`colors` attribute is no longer in the RelaxNG schema of the list view, so we can't use +it like before, but it looks like the RNG is not checked for embedded list.) + +## Testing + +Some views are overriden for demoing this module functionnalities: + +1. On the Users list view: The `name` and `login_date` fields are colored according to + conditions written in view definition. +2. On the Groups form view > "Access Rights": By renaming the rule name to a color (red, + blue, yellow, #00FDF0), the entire row background color is immediatly updated. +3. On the System Parameters list view: + - For the `key` field: Its content is the text color, the `value` field is its + background color. + - For the `value` field: Its content is the text color, the `value` field is its + background color. diff --git a/web_tree_dynamic_colored_field/readme/ROADMAP.md b/web_tree_dynamic_colored_field/readme/ROADMAP.md index 16376e95ff72..04f6b91a4a4a 100644 --- a/web_tree_dynamic_colored_field/readme/ROADMAP.md +++ b/web_tree_dynamic_colored_field/readme/ROADMAP.md @@ -1,7 +1 @@ -- Before version 13.0, this module had a feature allowing to change the - color of a line depending on a field, using a `colors` attribute with - the name of the field on the `` element. Since 13.0, the - `colors` attribute is no longer in the RelaxNG schema of the tree - view, so we can't use it anymore. This feature has then been dropped, - but could be reimplement in another way. - Since version 17.0 coloring is written into ``style`` attribute of (td) element diff --git a/web_tree_dynamic_colored_field/readme/USAGE.md b/web_tree_dynamic_colored_field/readme/USAGE.md index b5950598ff01..e531e34926de 100644 --- a/web_tree_dynamic_colored_field/readme/USAGE.md +++ b/web_tree_dynamic_colored_field/readme/USAGE.md @@ -1,70 +1,96 @@ -- In the tree view declaration, put - `options='{"bg_color": "red: customer==True"}` attribute in the +# Using view conditions + +- In the list view declaration, put `options='{"bg_color": "red: customer==True"}` + attribute in the `field` tag: + + ```xml + ... + + + ... + + ... + + + ... + ``` + + With this example, column which renders 'name' field will have its **background** + colored in red on customer records. + +- In the list view declaration, put `options='{"fg_color": "white:customer == True"}'` + attribute in the `field` tag: + + ```xml + ... + + + ... + + ... + + + ... + ``` + + With this example, column which renders 'name' field will have its **text** colored in + white on customer records. + +- If you want to use more than one color, you can split the attributes using ';': + + ``` + options='{"fg_color": "red:red_color == True; green:green_color == True"}' + ``` + + ```xml + ... + + + ... + + ... + + + ... + ``` + +- Can use strings too... In the list view declaration, put + `options="{'fg_color': 'green:customer_state == \'success\''}"` attribute in the `field` tag: - ... - - - ... - - ... - - - ... + ```xml + ... + + + ... + + ... + + + ... + ``` + +**Note that you can use single or normal quotes. If the declaration of the options +doesn't follow the JSON format, the options string will be evaluated using py.eval()** - With this example, column which renders 'name' field will have its **background** colored in red on customer records. +# Using view fields -- In the tree view declaration, put - `options='{"fg_color": "white:customer == True"}'` attribute in the +- In the list view declaration, put `options='{"bg_color": "my_color"}` attribute in the `field` tag: - ... - - - ... - - ... - - - ... - - With this example, column which renders 'name' field will have its **text** colored in white on customer records. - -- If you want to use more than one color, you can split the attributes - using ';': - -``` -options='{"fg_color": "red:red_color == True; green:green_color == True"}' -``` - -Example: - -``` xml -... - - - ... - - ... - - - ... -``` - -- Can use strings too... In the tree view declaration, put - `options="{'fg_color': 'green:customer_state == \'success\''}"` - attribute in the `field` tag: + ```xml + ... + + + ... + + + ... + + + ... + ``` - ... - - - ... - - ... - - - ... - -**Note that you can use single or normal quotes. If the declaration of -the options doesn't follow the JSON format, the options string will be -evaluated using py.eval()** + With this example, the content of the field named `my_color` will be used to populate + the `background-color` CSS value. Use a compute field to return whichever color you + want depending on the other record values. diff --git a/web_tree_dynamic_colored_field/static/description/index.html b/web_tree_dynamic_colored_field/static/description/index.html index 946fa0bb26d9..c7b3bd730f0a 100644 --- a/web_tree_dynamic_colored_field/static/description/index.html +++ b/web_tree_dynamic_colored_field/static/description/index.html @@ -370,95 +370,105 @@

Colorize field in tree views

!! source digest: sha256:9421f600f808456315bd58fa3ad58e5d8790f99fb1f0809e81ce7bb0ef0774b1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

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

-

This module aims to add support for dynamically coloring fields in tree +

This module aims to add support for dynamically coloring fields in list view according to data in the record.

Features

  • Add attribute bg_color on field’s options to color background -of a cell in tree view
  • +of a cell in list view
  • Add attribute fg_color on field’s options to change text color -of a cell in tree view
  • +of a cell in list view +
  • Add attribute bg_color_field on list’s colors to change +background color of the entire row in list view (*)
  • +
  • Add attribute fg_color_field on list’s colors to change text +color of the entire row in list view (*)
+

(*) This functionality only works for list defined in a form. Since +13.0, the colors attribute is no longer in the RelaxNG schema of the +list view, so we can’t use it like before, but it looks like the RNG is +not checked for embedded list.

Table of contents

+
+

Using view conditions

    -
  • In the tree view declaration, put +

  • In the list view declaration, put options='{"bg_color": "red: customer==True"} attribute in the field tag:

    -
    -...
    -<field name="arch" type="xml">
    -    <tree string="View name">
    -        ...
    -        <field name="name" options='{"bg_color": "red: customer == True"}'/>
    -        ...
    -    </tree>
    -</field>
    -...
    -
    -With this example, column which renders 'name' field will have its **background** colored in red on customer records.
    +
    +...
    +<field name="arch" type="xml">
    +    <list string="View name">
    +        ...
    +        <field name="name" options='{"bg_color": "red: customer == True"}'/>
    +        ...
    +    </list>
    +</field>
    +...
     
    +

    With this example, column which renders ‘name’ field will have its +background colored in red on customer records.

  • -
  • In the tree view declaration, put +

  • In the list view declaration, put options='{"fg_color": "white:customer == True"}' attribute in the field tag:

    -
    -...
    -<field name="arch" type="xml">
    -    <tree string="View name">
    -        ...
    -        <field name="name" options='{"fg_color": "white:customer == True"}'/>
    -        ...
    -    </tree>
    -</field>
    -...
    -
    -With this example, column which renders 'name' field will have its **text** colored in white on customer records.
    +
    +...
    +<field name="arch" type="xml">
    +    <list string="View name">
    +        ...
    +        <field name="name" options='{"fg_color": "white:customer == True"}'/>
    +        ...
    +    </list>
    +</field>
    +...
     
    +

    With this example, column which renders ‘name’ field will have its +text colored in white on customer records.

  • If you want to use more than one color, you can split the attributes using ‘;’:

    -
  • -
 options='{"fg_color": "red:red_color == True; green:green_color == True"}'
 
-

Example:

 ...
- <field name="arch" type="xml">
-     <tree string="View name">
-         ...
-         <field name="name" options='{"fg_color": "red:red_color == True; green:green_color == True"}'/>
-         ...
-     </tree>
- </field>
- ...
+<field name="arch" type="xml">
+    <list string="View name">
+        ...
+        <field name="name" options='{"fg_color": "red:red_color == True; green:green_color == True"}'/>
+        ...
+    </list>
+</field>
+...
 
-
    -
  • Can use strings too… In the tree view declaration, put +

  • +
  • Can use strings too… In the list view declaration, put options="{'fg_color': 'green:customer_state == \'success\''}" attribute in the field tag:

    -
    -...
    -<field name="arch" type="xml">
    -    <tree string="View name">
    -        ...
    -        <field name="name" options="{'fg_color': 'green:customer_state == \'success\''}"/>
    -        ...
    -    </tree>
    -</field>
    -...
    +
    +...
    +<field name="arch" type="xml">
    +    <list string="View name">
    +        ...
    +        <field name="name" options="{'fg_color': 'green:customer_state == \'success\''}"/>
    +        ...
    +    </list>
    +</field>
    +...
     
@@ -466,21 +476,39 @@

Usage

the options doesn’t follow the JSON format, the options string will be evaluated using py.eval()

+
+

Using view fields

+
    +
  • In the list view declaration, put +options='{"bg_color": "my_color"} attribute in the field tag:

    +
    +...
    +<field name="arch" type="xml">
    +    <list string="View name">
    +        ...
    +        <field name="my_color" column_invisible="1"/>
    +        <field name="name" options='{"bg_color": "my_color"}'/>
    +        ...
    +    </list>
    +</field>
    +...
    +
    +

    With this example, the content of the field named my_color will be +used to populate the background-color CSS value. Use a compute +field to return whichever color you want depending on the other record +values.

    +
  • +
+
-

Known issues / Roadmap

+

Known issues / Roadmap

    -
  • Before version 13.0, this module had a feature allowing to change the -color of a line depending on a field, using a colors attribute -with the name of the field on the <tree> element. Since 13.0, the -colors attribute is no longer in the RelaxNG schema of the tree -view, so we can’t use it anymore. This feature has then been dropped, -but could be reimplement in another way.
  • Since version 17.0 coloring is written into style attribute of (td) element
-

Bug Tracker

+

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 @@ -488,7 +516,7 @@

Bug Tracker

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

@@ -508,6 +536,7 @@

Contributors

  • Phuc Tran Thanh <phuc@trobz.com>
  • Sylvain LE GAL <https://twitter.com/legalsylvain>
  • Jurgis Pralgauskis <jurgis@versada.eu>
  • +
  • Yann Papouin <ypa@decgroupe.com>
  • diff --git a/web_tree_dynamic_colored_field/static/src/js/list_renderer.esm.js b/web_tree_dynamic_colored_field/static/src/js/list_renderer.esm.js index 76612d4cb711..b046498b9e84 100644 --- a/web_tree_dynamic_colored_field/static/src/js/list_renderer.esm.js +++ b/web_tree_dynamic_colored_field/static/src/js/list_renderer.esm.js @@ -3,6 +3,40 @@ import {evaluateBooleanExpr} from "@web/core/py_js/py"; import {patch} from "@web/core/utils/patch"; patch(ListRenderer.prototype, { + setup() { + super.setup(...arguments); + this.assignDefaultColorFields(); + }, + + /** + * Look up for a `fg_color_field` or `bg_color_field` parameter in list `colors` attribute + */ + assignDefaultColorFields() { + this.fgColorField = null; + this.bgColorField = null; + if ("colors" in this.props.archInfo.xmlDoc.attributes) { + // Colors attribute is present in the view definition + const colorAttr = + this.props.archInfo.xmlDoc.attributes.colors.value.split(";"); + for (var i = 0, len = colorAttr.length; i < len; i++) { + var attr = colorAttr[i].split(":"); + if (attr.length == 2) { + var colorType = attr[0].trim(); + var colorField = attr[1].trim(); + if (colorType && colorField) { + if (colorType === "fg_color_field") { + this.fgColorField = colorField; + } else if (colorType === "bg_color_field") { + this.bgColorField = colorField; + } + } + } else { + console.warn("Invalid colors attribute:", attr); + } + } + } + }, + /** * @param {Object} column represents field * @param {Record} record @@ -11,17 +45,33 @@ patch(ListRenderer.prototype, { getDynamicColoredStyle(column, record) { let style = ""; - let color = this.getDynamicColor(column, record, "bg_color"); - if (color !== undefined) { - style += `background-color: ${color};`; - } + // 1. Get dynamic colors from column options + let backgroundColor = this.getDynamicColor(column, record, "bg_color"); + let foregroundColor = this.getDynamicColor(column, record, "fg_color"); - color = this.getDynamicColor(column, record, "fg_color"); - if (color !== undefined) { - // $td.css('color', color); - style += `color: ${color};`; + // 2. Get colors from specified fields in record data only if not set dynamically + if (!backgroundColor && this.bgColorField) { + if (this.bgColorField in record.data) { + backgroundColor = record.data[this.bgColorField]; + } else { + console.warn(`No field named "${this.bgColorField}" present in view.`); + } + } + if (!foregroundColor && this.fgColorField) { + if (this.fgColorField in record.data) { + foregroundColor = record.data[this.fgColorField]; + } else { + console.warn(`No field named "${this.fgColorField}" present in view.`); + } } + // Apply styles + if (backgroundColor !== undefined) { + style += `background-color: ${backgroundColor};`; + } + if (foregroundColor !== undefined) { + style += `color: ${foregroundColor};`; + } return style; }, @@ -40,7 +90,12 @@ patch(ListRenderer.prototype, { for (const color_def of definition.split(";")) { const color_to_expression = this.pairColorParse(color_def); if (color_to_expression !== undefined) { - const [color, expression] = color_to_expression; + var [color, expression] = color_to_expression; + // Check if color is a named field in record + // and if so, get its value + if (color in record.data) { + color = record.data[color]; + } if ( evaluateBooleanExpr( expression, @@ -69,7 +124,7 @@ patch(ListRenderer.prototype, { // If one passes a bare color instead of an expression, // then we consider that color is to be shown in any case expression = pairList[1] ? pairList[1] : "True"; - return [color, expression]; + return [color.trim(), expression.trim()]; } return undefined; },