diff --git a/setup/web_widget_x2many_2d_matrix/odoo/addons/web_widget_x2many_2d_matrix b/setup/web_widget_x2many_2d_matrix/odoo/addons/web_widget_x2many_2d_matrix new file mode 120000 index 000000000000..4d06f547dda2 --- /dev/null +++ b/setup/web_widget_x2many_2d_matrix/odoo/addons/web_widget_x2many_2d_matrix @@ -0,0 +1 @@ +../../../../web_widget_x2many_2d_matrix \ No newline at end of file diff --git a/setup/web_widget_x2many_2d_matrix/setup.py b/setup/web_widget_x2many_2d_matrix/setup.py new file mode 100644 index 000000000000..28c57bb64031 --- /dev/null +++ b/setup/web_widget_x2many_2d_matrix/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/web_widget_x2many_2d_matrix/README.rst b/web_widget_x2many_2d_matrix/README.rst new file mode 100644 index 000000000000..5eac3e9dcafa --- /dev/null +++ b/web_widget_x2many_2d_matrix/README.rst @@ -0,0 +1,249 @@ +=========================== +2D matrix for x2many fields +=========================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/15.0/web_widget_x2many_2d_matrix + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-15-0/web-15-0-web_widget_x2many_2d_matrix + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/162/15.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to show an x2many field with 3-tuples +($x_value, $y_value, $value) in a table + ++-----------+-------------+-------------+ +| | $x_value1 | $x_value2 | ++===========+=============+=============+ +| $y_value1 | $value(1/1) | $value(2/1) | ++-----------+-------------+-------------+ +| $y_value2 | $value(1/2) | $value(2/2) | ++-----------+-------------+-------------+ + +where `value(n/n)` is editable. + +An example use case would be: Select some projects and some employees so that +a manager can easily fill in the planned_hours for one task per employee. The +result could look like this: + +.. image:: https://raw.githubusercontent.com/OCA/web/12.0/web_widget_x2many_2d_matrix/static/description/screenshot.png + :alt: Screenshot + +The beauty of this is that you have an arbitrary amount of columns with this +widget, trying to get this in standard x2many lists involves some quite ugly +hacks. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Use this widget by saying:: + + + +This assumes that my_field refers to a model with the fields `x`, `y` and +`value`. If your fields are named differently, pass the correct names as +attributes: + +.. code-block:: xml + + + + + + + + + + +You can pass the following parameters: + +field_x_axis + The field that indicates the x value of a point +field_y_axis + The field that indicates the y value of a point +field_label_x_axis + Use another field to display in the table header +field_label_y_axis + Use another field to display in the table header +field_value + Show this field as value +show_row_totals + If field_value is a numeric field, it indicates if you want to calculate + row totals. True by default +show_column_totals + If field_value is a numeric field, it indicates if you want to calculate + column totals. True by default + +Example +~~~~~~~ + +You need a data structure already filled with values. Let's assume we want to +use this widget in a wizard that lets the user fill in planned hours for one +task per project per user. In this case, we can use ``project.task`` as our +data model and point to it from our wizard. The crucial part is that we fill +the field in the default function: + +.. code-block:: python + + from odoo import fields, models + + class MyWizard(models.TransientModel): + _name = 'my.wizard' + + def _default_task_ids(self): + # your list of project should come from the context, some selection + # in a previous wizard or wherever else + projects = self.env['project.project'].browse([1, 2, 3]) + # same with users + users = self.env['res.users'].browse([1, 2, 3]) + return [ + (0, 0, { + 'name': 'Sample task name', + 'project_id': p.id, + 'user_id': u.id, + 'planned_hours': 0, + 'message_needaction': False, + 'date_deadline': fields.Date.today(), + }) + # if the project doesn't have a task for the user, + # create a new one + if not p.task_ids.filtered(lambda x: x.user_id == u) else + # otherwise, return the task + (4, p.task_ids.filtered(lambda x: x.user_id == u)[0].id) + for p in projects + for u in users + ] + + task_ids = fields.Many2many('project.task', default=_default_task_ids) + +Now in our wizard, we can use: + +.. code-block:: xml + + + + + + + + + + +Known issues / Roadmap +====================== + +* Support extra attributes on each field cell via `field_extra_attrs` param. + We could set a cell as not editable, required or readonly for instance. + The `readonly` case will also give the ability + to click on m2o to open related records. + +* Support limit total records in the matrix. Ref: https://github.com/OCA/web/issues/901 + +* Support cell traversal through keyboard arrows. + +* Entering the widget from behind by pressing ``Shift+TAB`` in your keyboard + will enter into the 1st cell until https://github.com/odoo/odoo/pull/26490 + is merged. + +* Support extra invisible fields inside each cell. + +* Support kanban mode. Current behaviour forces list mode. + +Changelog +========= + +12.0.1.0.1 (2018-12-07) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [FIX] Cells are unable to render property. + (`#1126 `_) + +12.0.1.0.0 (2018-11-20) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [12.0][MIG] web_widget_x2many_2d_matrix + (`#1101 `_) + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Therp BV +* Tecnativa +* Camptocamp +* CorporateHub + +Contributors +~~~~~~~~~~~~ + +* Holger Brunn +* Pedro M. Baeza +* Artem Kostyuk +* Simone Orsi +* Timon Tschanz +* Jairo Llopis +* Dennis Sluijk +* `CorporateHub `__ + + * Alexey Pelykh + +* Adrià Gil Sorribes +* Christopher Ormaza + +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-ChrisOForgeFlow| image:: https://github.com/ChrisOForgeFlow.png?size=40px + :target: https://github.com/ChrisOForgeFlow + :alt: ChrisOForgeFlow + +Current `maintainer `__: + +|maintainer-ChrisOForgeFlow| + +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_x2many_2d_matrix/__init__.py b/web_widget_x2many_2d_matrix/__init__.py new file mode 100644 index 000000000000..ef5ae3587f59 --- /dev/null +++ b/web_widget_x2many_2d_matrix/__init__.py @@ -0,0 +1 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). diff --git a/web_widget_x2many_2d_matrix/__manifest__.py b/web_widget_x2many_2d_matrix/__manifest__.py new file mode 100644 index 000000000000..eb38ecb28586 --- /dev/null +++ b/web_widget_x2many_2d_matrix/__manifest__.py @@ -0,0 +1,40 @@ +# Copyright 2015 Holger Brunn +# Copyright 2016 Pedro M. Baeza +# Copyright 2018 Simone Orsi +# Copyright 2020 CorporateHub (https://corporatehub.eu) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{ + "name": "2D matrix for x2many fields", + "version": "16.0.1.0.0", + "maintainers": ["ChrisOForgeFlow"], + "development_status": "Production/Stable", + "author": ( + "Therp BV, " + "Tecnativa, " + "Camptocamp, " + "CorporateHub, " + "Onestein, " + "Odoo Community Association (OCA)" + ), + "website": "https://github.com/OCA/web", + "license": "AGPL-3", + "category": "Hidden/Dependency", + "summary": "Show list fields as a matrix", + "depends": ["web"], + "data": [], + "installable": True, + "assets": { + "web.assets_backend": [ + "web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_renderer/" + "x2many_2d_matrix_renderer.esm.js", + "web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_renderer/" + "x2many_2d_matrix_renderer.xml", + "web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/" + "x2many_2d_matrix_field.esm.js", + "web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/" + "x2many_2d_matrix_field.xml", + "web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/" + "x2many_2d_matrix_field.scss", + ], + }, +} diff --git a/web_widget_x2many_2d_matrix/i18n/ar.po b/web_widget_x2many_2d_matrix/i18n/ar.po new file mode 100644 index 000000000000..eb7d2074b25a --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/ar.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +# Translators: +# SaFi J. , 2015 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-16 07:41+0000\n" +"PO-Revision-Date: 2015-12-16 17:24+0000\n" +"Last-Translator: SaFi J. \n" +"Language-Team: Arabic (http://www.transifex.com/oca/OCA-web-8-0/language/" +"ar/)\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, fuzzy, python-format +msgid "Sum Total" +msgstr "المجموع الاجمالي" diff --git a/web_widget_x2many_2d_matrix/i18n/de.po b/web_widget_x2many_2d_matrix/i18n/de.po new file mode 100644 index 000000000000..794e556579d6 --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/de.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +# Translators: +# Rudolf Schnapka , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-10 07:31+0000\n" +"PO-Revision-Date: 2020-07-22 12:19+0000\n" +"Last-Translator: c2cdidier \n" +"Language-Team: German (http://www.transifex.com/oca/OCA-web-8-0/language/de/)" +"\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.10\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "Leider keine Matrixdaten zur Anzeige." + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "Summe" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum Total" +msgstr "Gesamtsumme" diff --git a/web_widget_x2many_2d_matrix/i18n/es.po b/web_widget_x2many_2d_matrix/i18n/es.po new file mode 100644 index 000000000000..bce9429f446b --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/es.po @@ -0,0 +1,40 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-11-23 13:46+0000\n" +"PO-Revision-Date: 2015-11-07 11:29+0000\n" +"Last-Translator: Pedro M. Baeza \n" +"Language-Team: Spanish (http://www.transifex.com/oca/OCA-web-8-0/language/" +"es/)\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, fuzzy, python-format +msgid "Sum Total" +msgstr "Total" diff --git a/web_widget_x2many_2d_matrix/i18n/fi.po b/web_widget_x2many_2d_matrix/i18n/fi.po new file mode 100644 index 000000000000..d1ef1abe9337 --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/fi.po @@ -0,0 +1,41 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +# Translators: +# Jarmo Kortetjärvi , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-10 07:31+0000\n" +"PO-Revision-Date: 2016-02-01 09:54+0000\n" +"Last-Translator: Jarmo Kortetjärvi \n" +"Language-Team: Finnish (http://www.transifex.com/oca/OCA-web-8-0/language/" +"fi/)\n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, fuzzy, python-format +msgid "Sum Total" +msgstr "Yhteensä" diff --git a/web_widget_x2many_2d_matrix/i18n/fr.po b/web_widget_x2many_2d_matrix/i18n/fr.po new file mode 100644 index 000000000000..14c560d51815 --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/fr.po @@ -0,0 +1,41 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-05-06 15:50+0000\n" +"PO-Revision-Date: 2019-08-06 12:44+0000\n" +"Last-Translator: Nicolas JEUDY \n" +"Language-Team: French (http://www.transifex.com/oca/OCA-web-8-0/language/" +"fr/)\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.7.1\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "Désolé il n'y a pas de donnée matrice à afficher." + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "Somme" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum Total" +msgstr "Total" diff --git a/web_widget_x2many_2d_matrix/i18n/hr.po b/web_widget_x2many_2d_matrix/i18n/hr.po new file mode 100644 index 000000000000..9237549f0167 --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/hr.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +# Translators: +# Ana-Maria Olujić , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-08-25 00:51+0000\n" +"PO-Revision-Date: 2019-11-14 10:34+0000\n" +"Last-Translator: Bole \n" +"Language-Team: Croatian (http://www.transifex.com/oca/OCA-web-8-0/language/" +"hr/)\n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 3.8\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "Oprostite, nema matrice podataka za prikaz." + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "Suma" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum Total" +msgstr "Ukupno" diff --git a/web_widget_x2many_2d_matrix/i18n/it.po b/web_widget_x2many_2d_matrix/i18n/it.po new file mode 100644 index 000000000000..961ba8e4814b --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/it.po @@ -0,0 +1,41 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-17 07:30+0000\n" +"PO-Revision-Date: 2019-05-03 11:03+0000\n" +"Last-Translator: gslabit \n" +"Language-Team: Italian (http://www.transifex.com/oca/OCA-web-8-0/language/" +"it/)\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.5.1\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "Spiacenti, nessun dato da visualizzare." + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "Somma" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum Total" +msgstr "Totale" diff --git a/web_widget_x2many_2d_matrix/i18n/lt.po b/web_widget_x2many_2d_matrix/i18n/lt.po new file mode 100644 index 000000000000..2527d416e8da --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/lt.po @@ -0,0 +1,41 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +# Translators: +# Viktoras Norkus , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-25 01:58+0000\n" +"PO-Revision-Date: 2018-02-15 12:40+0200\n" +"Last-Translator: Viktoras Norkus , 2018\n" +"Language-Team: Lithuanian (https://www.transifex.com/oca/teams/23907/lt/)\n" +"Language: lt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n" +"%100<10 || n%100>=20) ? 1 : 2);\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, fuzzy, python-format +msgid "Sum Total" +msgstr "Suma" diff --git a/web_widget_x2many_2d_matrix/i18n/nl.po b/web_widget_x2many_2d_matrix/i18n/nl.po new file mode 100644 index 000000000000..045d70337dc1 --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/nl.po @@ -0,0 +1,39 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-04-22 15:47+0000\n" +"Last-Translator: Bosd \n" +"Language-Team: none\n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "Sorry er is geen matrix data om weertegeven." + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "Som" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum Total" +msgstr "Totaal" diff --git a/web_widget_x2many_2d_matrix/i18n/nl_NL.po b/web_widget_x2many_2d_matrix/i18n/nl_NL.po new file mode 100644 index 000000000000..e31a9053debb --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/nl_NL.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +# Translators: +# Peter Hageman , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-03 03:50+0000\n" +"PO-Revision-Date: 2021-04-22 15:47+0000\n" +"Last-Translator: Bosd \n" +"Language-Team: Dutch (Netherlands) (https://www.transifex.com/oca/teams/" +"23907/nl_NL/)\n" +"Language: nl_NL\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum Total" +msgstr "Totaal" diff --git a/web_widget_x2many_2d_matrix/i18n/pt_BR.po b/web_widget_x2many_2d_matrix/i18n/pt_BR.po new file mode 100644 index 000000000000..06052d6fa65c --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/pt_BR.po @@ -0,0 +1,41 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-11 02:18+0000\n" +"PO-Revision-Date: 2019-09-03 01:23+0000\n" +"Last-Translator: Rodrigo Macedo \n" +"Language-Team: Portuguese (Brazil) (http://www.transifex.com/oca/OCA-web-8-0/" +"language/pt_BR/)\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.8\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "Desculpe não há dados de matriz para exibir." + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "Soma" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum Total" +msgstr "Soma Total" diff --git a/web_widget_x2many_2d_matrix/i18n/sl.po b/web_widget_x2many_2d_matrix/i18n/sl.po new file mode 100644 index 000000000000..48e4d8a4f7f5 --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/sl.po @@ -0,0 +1,41 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-11-23 13:46+0000\n" +"PO-Revision-Date: 2015-11-08 05:48+0000\n" +"Last-Translator: Matjaž Mozetič \n" +"Language-Team: Slovenian (http://www.transifex.com/oca/OCA-web-8-0/language/" +"sl/)\n" +"Language: sl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n" +"%100==4 ? 2 : 3);\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, fuzzy, python-format +msgid "Sum Total" +msgstr "Skupaj" diff --git a/web_widget_x2many_2d_matrix/i18n/tr.po b/web_widget_x2many_2d_matrix/i18n/tr.po new file mode 100644 index 000000000000..e27e5a894733 --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/tr.po @@ -0,0 +1,41 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +# Translators: +# Ahmet Altınışık , 2015 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-08 21:34+0000\n" +"PO-Revision-Date: 2015-12-30 22:00+0000\n" +"Last-Translator: Ahmet Altınışık \n" +"Language-Team: Turkish (http://www.transifex.com/oca/OCA-web-8-0/language/" +"tr/)\n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, fuzzy, python-format +msgid "Sum Total" +msgstr "Toplam" diff --git a/web_widget_x2many_2d_matrix/i18n/web_widget_x2many_2d_matrix.pot b/web_widget_x2many_2d_matrix/i18n/web_widget_x2many_2d_matrix.pot new file mode 100644 index 000000000000..842e044e0e73 --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/web_widget_x2many_2d_matrix.pot @@ -0,0 +1,36 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum Total" +msgstr "" diff --git a/web_widget_x2many_2d_matrix/i18n/zh_CN.po b/web_widget_x2many_2d_matrix/i18n/zh_CN.po new file mode 100644 index 000000000000..caca30c87104 --- /dev/null +++ b/web_widget_x2many_2d_matrix/i18n/zh_CN.po @@ -0,0 +1,38 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_x2many_2d_matrix +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2019-09-01 17:23+0000\n" +"Last-Translator: 黎伟杰 <674416404@qq.com>\n" +"Language-Team: none\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 3.8\n" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sorry no matrix data to display." +msgstr "抱歉没有要显示的矩阵数据。" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum" +msgstr "总和" + +#. module: web_widget_x2many_2d_matrix +#. openerp-web +#: code:addons/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js:0 +#, python-format +msgid "Sum Total" +msgstr "总和" diff --git a/web_widget_x2many_2d_matrix/readme/CONTRIBUTORS.rst b/web_widget_x2many_2d_matrix/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000000..945e85d5ce93 --- /dev/null +++ b/web_widget_x2many_2d_matrix/readme/CONTRIBUTORS.rst @@ -0,0 +1,13 @@ +* Holger Brunn +* Pedro M. Baeza +* Artem Kostyuk +* Simone Orsi +* Timon Tschanz +* Jairo Llopis +* Dennis Sluijk +* `CorporateHub `__ + + * Alexey Pelykh + +* Adrià Gil Sorribes +* Christopher Ormaza diff --git a/web_widget_x2many_2d_matrix/readme/DESCRIPTION.rst b/web_widget_x2many_2d_matrix/readme/DESCRIPTION.rst new file mode 100644 index 000000000000..d3f10cae8eef --- /dev/null +++ b/web_widget_x2many_2d_matrix/readme/DESCRIPTION.rst @@ -0,0 +1,23 @@ +This module allows to show an x2many field with 3-tuples +($x_value, $y_value, $value) in a table + ++-----------+-------------+-------------+ +| | $x_value1 | $x_value2 | ++===========+=============+=============+ +| $y_value1 | $value(1/1) | $value(2/1) | ++-----------+-------------+-------------+ +| $y_value2 | $value(1/2) | $value(2/2) | ++-----------+-------------+-------------+ + +where `value(n/n)` is editable. + +An example use case would be: Select some projects and some employees so that +a manager can easily fill in the planned_hours for one task per employee. The +result could look like this: + +.. image:: https://raw.githubusercontent.com/OCA/web/12.0/web_widget_x2many_2d_matrix/static/description/screenshot.png + :alt: Screenshot + +The beauty of this is that you have an arbitrary amount of columns with this +widget, trying to get this in standard x2many lists involves some quite ugly +hacks. diff --git a/web_widget_x2many_2d_matrix/readme/HISTORY.rst b/web_widget_x2many_2d_matrix/readme/HISTORY.rst new file mode 100644 index 000000000000..8bad8c46cd42 --- /dev/null +++ b/web_widget_x2many_2d_matrix/readme/HISTORY.rst @@ -0,0 +1,11 @@ +12.0.1.0.1 (2018-12-07) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [FIX] Cells are unable to render property. + (`#1126 `_) + +12.0.1.0.0 (2018-11-20) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [12.0][MIG] web_widget_x2many_2d_matrix + (`#1101 `_) diff --git a/web_widget_x2many_2d_matrix/readme/ROADMAP.rst b/web_widget_x2many_2d_matrix/readme/ROADMAP.rst new file mode 100644 index 000000000000..1dc1a84dacf7 --- /dev/null +++ b/web_widget_x2many_2d_matrix/readme/ROADMAP.rst @@ -0,0 +1,16 @@ +* Support extra attributes on each field cell via `field_extra_attrs` param. + We could set a cell as not editable, required or readonly for instance. + The `readonly` case will also give the ability + to click on m2o to open related records. + +* Support limit total records in the matrix. Ref: https://github.com/OCA/web/issues/901 + +* Support cell traversal through keyboard arrows. + +* Entering the widget from behind by pressing ``Shift+TAB`` in your keyboard + will enter into the 1st cell until https://github.com/odoo/odoo/pull/26490 + is merged. + +* Support extra invisible fields inside each cell. + +* Support kanban mode. Current behaviour forces list mode. diff --git a/web_widget_x2many_2d_matrix/readme/USAGE.rst b/web_widget_x2many_2d_matrix/readme/USAGE.rst new file mode 100644 index 000000000000..bab81c79b3c3 --- /dev/null +++ b/web_widget_x2many_2d_matrix/readme/USAGE.rst @@ -0,0 +1,88 @@ +Use this widget by saying:: + + + +This assumes that my_field refers to a model with the fields `x`, `y` and +`value`. If your fields are named differently, pass the correct names as +attributes: + +.. code-block:: xml + + + + + + + + + + +You can pass the following parameters: + +field_x_axis + The field that indicates the x value of a point +field_y_axis + The field that indicates the y value of a point +field_value + Show this field as value +show_row_totals + If field_value is a numeric field, it indicates if you want to calculate + row totals. True by default +show_column_totals + If field_value is a numeric field, it indicates if you want to calculate + column totals. True by default + +Example +~~~~~~~ + +You need a data structure already filled with values. Let's assume we want to +use this widget in a wizard that lets the user fill in planned hours for one +task per project per user. In this case, we can use ``project.task`` as our +data model and point to it from our wizard. The crucial part is that we fill +the field in the default function: + +.. code-block:: python + + from odoo import fields, models + + class MyWizard(models.TransientModel): + _name = 'my.wizard' + + def _default_task_ids(self): + # your list of project should come from the context, some selection + # in a previous wizard or wherever else + projects = self.env['project.project'].browse([1, 2, 3]) + # same with users + users = self.env['res.users'].browse([1, 2, 3]) + return [ + (0, 0, { + 'name': 'Sample task name', + 'project_id': p.id, + 'user_id': u.id, + 'planned_hours': 0, + 'message_needaction': False, + 'date_deadline': fields.Date.today(), + }) + # if the project doesn't have a task for the user, + # create a new one + if not p.task_ids.filtered(lambda x: x.user_id == u) else + # otherwise, return the task + (4, p.task_ids.filtered(lambda x: x.user_id == u)[0].id) + for p in projects + for u in users + ] + + task_ids = fields.Many2many('project.task', default=_default_task_ids) + +Now in our wizard, we can use: + +.. code-block:: xml + + + + + + + + + diff --git a/web_widget_x2many_2d_matrix/static/description/icon.png b/web_widget_x2many_2d_matrix/static/description/icon.png new file mode 100644 index 000000000000..a501fbf835ea Binary files /dev/null and b/web_widget_x2many_2d_matrix/static/description/icon.png differ diff --git a/web_widget_x2many_2d_matrix/static/description/index.html b/web_widget_x2many_2d_matrix/static/description/index.html new file mode 100644 index 000000000000..0d70b6f6b6c6 --- /dev/null +++ b/web_widget_x2many_2d_matrix/static/description/index.html @@ -0,0 +1,601 @@ + + + + + + +2D matrix for x2many fields + + + +
+

2D matrix for x2many fields

+ + +

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

+

This module allows to show an x2many field with 3-tuples +($x_value, $y_value, $value) in a table

+ +++++ + + + + + + + + + + + + + + + + +
 $x_value1$x_value2
$y_value1$value(1/1)$value(2/1)
$y_value2$value(1/2)$value(2/2)
+

where value(n/n) is editable.

+

An example use case would be: Select some projects and some employees so that +a manager can easily fill in the planned_hours for one task per employee. The +result could look like this:

+Screenshot +

The beauty of this is that you have an arbitrary amount of columns with this +widget, trying to get this in standard x2many lists involves some quite ugly +hacks.

+

Table of contents

+ +
+

Usage

+

Use this widget by saying:

+
+<field name="my_field" widget="x2many_2d_matrix" />
+
+

This assumes that my_field refers to a model with the fields x, y and +value. If your fields are named differently, pass the correct names as +attributes:

+
+<field name="my_field" widget="x2many_2d_matrix" field_x_axis="my_field1" field_y_axis="my_field2" field_value="my_field3">
+    <tree>
+        <field name="my_field"/>
+        <field name="my_field1"/>
+        <field name="my_field2"/>
+        <field name="my_field3"/>
+    </tree>
+</field>
+
+

You can pass the following parameters:

+
+
field_x_axis
+
The field that indicates the x value of a point
+
field_y_axis
+
The field that indicates the y value of a point
+
field_label_x_axis
+
Use another field to display in the table header
+
field_label_y_axis
+
Use another field to display in the table header
+
field_value
+
Show this field as value
+
show_row_totals
+
If field_value is a numeric field, it indicates if you want to calculate +row totals. True by default
+
show_column_totals
+
If field_value is a numeric field, it indicates if you want to calculate +column totals. True by default
+
+
+

Example

+

You need a data structure already filled with values. Let’s assume we want to +use this widget in a wizard that lets the user fill in planned hours for one +task per project per user. In this case, we can use project.task as our +data model and point to it from our wizard. The crucial part is that we fill +the field in the default function:

+
+from odoo import fields, models
+
+class MyWizard(models.TransientModel):
+    _name = 'my.wizard'
+
+    def _default_task_ids(self):
+        # your list of project should come from the context, some selection
+        # in a previous wizard or wherever else
+        projects = self.env['project.project'].browse([1, 2, 3])
+        # same with users
+        users = self.env['res.users'].browse([1, 2, 3])
+        return [
+            (0, 0, {
+                'name': 'Sample task name',
+                'project_id': p.id,
+                'user_id': u.id,
+                'planned_hours': 0,
+                'message_needaction': False,
+                'date_deadline': fields.Date.today(),
+            })
+            # if the project doesn't have a task for the user,
+            # create a new one
+            if not p.task_ids.filtered(lambda x: x.user_id == u) else
+            # otherwise, return the task
+            (4, p.task_ids.filtered(lambda x: x.user_id == u)[0].id)
+            for p in projects
+            for u in users
+        ]
+
+    task_ids = fields.Many2many('project.task', default=_default_task_ids)
+
+

Now in our wizard, we can use:

+
+<field name="task_ids" widget="x2many_2d_matrix" field_x_axis="project_id" field_y_axis="user_id" field_value="planned_hours">
+    <tree>
+        <field name="task_ids"/>
+        <field name="project_id"/>
+        <field name="user_id"/>
+        <field name="planned_hours"/>
+    </tree>
+</field>
+
+
+
+
+

Known issues / Roadmap

+
    +
  • Support extra attributes on each field cell via field_extra_attrs param. +We could set a cell as not editable, required or readonly for instance. +The readonly case will also give the ability +to click on m2o to open related records.
  • +
  • Support limit total records in the matrix. Ref: https://github.com/OCA/web/issues/901
  • +
  • Support cell traversal through keyboard arrows.
  • +
  • Entering the widget from behind by pressing Shift+TAB in your keyboard +will enter into the 1st cell until https://github.com/odoo/odoo/pull/26490 +is merged.
  • +
  • Support extra invisible fields inside each cell.
  • +
  • Support kanban mode. Current behaviour forces list mode.
  • +
+
+
+

Changelog

+
+

12.0.1.0.1 (2018-12-07)

+
    +
  • [FIX] Cells are unable to render property. +(#1126)
  • +
+
+
+

12.0.1.0.0 (2018-11-20)

+
    +
  • [12.0][MIG] web_widget_x2many_2d_matrix +(#1101)
  • +
+
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Therp BV
  • +
  • Tecnativa
  • +
  • Camptocamp
  • +
  • CorporateHub
  • +
+
+
+

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:

+

ChrisOForgeFlow

+

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_x2many_2d_matrix/static/description/screenshot.png b/web_widget_x2many_2d_matrix/static/description/screenshot.png new file mode 100644 index 000000000000..4b75baa8aa91 Binary files /dev/null and b/web_widget_x2many_2d_matrix/static/description/screenshot.png differ diff --git a/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/x2many_2d_matrix_field.esm.js b/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/x2many_2d_matrix_field.esm.js new file mode 100644 index 000000000000..a0a71442f47c --- /dev/null +++ b/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/x2many_2d_matrix_field.esm.js @@ -0,0 +1,100 @@ +/** @odoo-module **/ + +import {Component} from "@odoo/owl"; +import {standardFieldProps} from "@web/views/fields/standard_field_props"; +import {registry} from "@web/core/registry"; +import {archParseBoolean} from "@web/views/utils"; +import {X2Many2DMatrixRenderer} from "@web_widget_x2many_2d_matrix/components/x2many_2d_matrix_renderer/x2many_2d_matrix_renderer.esm"; + +export class X2Many2DMatrixField extends Component { + setup() { + this.activeField = this.props.record.activeFields[this.props.name]; + } + + getList() { + return this.props.value; + } + + get list() { + return this.getList(); + } + + _getDefaultRecordValues() { + return {}; + } + + async commitChange(x, y, value) { + const fields = this.props.matrixFields; + const values = this._getDefaultRecordValues(); + + const matchingRecords = this.list.records.filter((record) => { + let recordX = record.data[fields.x]; + let recordY = record.data[fields.y]; + if (record.fields[fields.x].type === "many2one") { + recordX = recordX[0]; + } + if (record.fields[fields.y].type === "many2one") { + recordY = recordY[0]; + } + return recordX === x && recordY === y; + }); + if (matchingRecords.length === 1) { + values[fields.value] = value; + await matchingRecords[0].update(values); + } else { + values[fields.x] = x; + values[fields.y] = y; + + if (this.list.fields[this.props.matrixFields.x].type === "many2one") { + values[fields.x] = [x, "/"]; + } + if (this.list.fields[this.props.matrixFields.y].type === "many2one") { + values[fields.y] = [y, "/"]; + } + + let total = 0; + if (matchingRecords.length) { + total = matchingRecords + .map((r) => r.data[fields.value]) + .reduce((aggr, v) => aggr + v); + } + const diff = value - total; + values[fields.value] = diff; + const record = await this.list.addNew({ + mode: "edit", + }); + await record.update(values); + } + this.props.setDirty(false); + } +} + +X2Many2DMatrixField.template = "web_widget_x2many_2d_matrix.X2Many2DMatrixField"; +X2Many2DMatrixField.props = { + ...standardFieldProps, + matrixFields: Object, + isXClickable: Boolean, + isYClickable: Boolean, + showRowTotals: Boolean, + showColumnTotals: Boolean, +}; +X2Many2DMatrixField.components = {X2Many2DMatrixRenderer}; +X2Many2DMatrixField.extractProps = ({attrs}) => { + return { + matrixFields: { + value: attrs.field_value, + x: attrs.field_x_axis, + y: attrs.field_y_axis, + }, + isXClickable: archParseBoolean(attrs.x_axis_clickable), + isYClickable: archParseBoolean(attrs.y_axis_clickable), + showRowTotals: + "show_row_totals" in attrs ? archParseBoolean(attrs.show_row_totals) : true, + showColumnTotals: + "show_column_totals" in attrs + ? archParseBoolean(attrs.show_column_totals) + : true, + }; +}; + +registry.category("fields").add("x2many_2d_matrix", X2Many2DMatrixField); diff --git a/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/x2many_2d_matrix_field.scss b/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/x2many_2d_matrix_field.scss new file mode 100644 index 000000000000..424527189acd --- /dev/null +++ b/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/x2many_2d_matrix_field.scss @@ -0,0 +1,73 @@ +$x2many_2d_matrix_max_height: 450px; + +.o_form_view .o_field_x2many_2d_matrix { + .table-responsive { + max-height: $x2many_2d_matrix_max_height; + overflow-y: auto; + } + + .table { + > thead > tr > th { + white-space: pre-line; + position: sticky; + top: 0; + z-index: 1; + background-color: $o-list-footer-bg-color; + + &.total { + right: 0; + } + } + + > tbody { + > tr { + &:nth-of-type(2n + 1) td.row-total, + &:nth-of-type(2n + 1) td:first-child { + background-color: mix(#000, #fff, 1%); + } + &:nth-of-type(2n) td.row-total, + &:nth-of-type(2n) td:first-child { + background-color: white; + } + + > td { + text-align: left; + + &:first-child { + position: sticky; + left: 0; + border-right-width: 1px; + border-right-color: $gray-300; + border-right-style: solid; + box-shadow: -1px 5px 10px $gray-300; + } + &.row-total { + padding: 0.75rem; + font-weight: bold; + position: sticky; + right: 0; + border-left-width: 1px; + border-left-color: $gray-300; + border-left-style: solid; + box-shadow: -1px 5px 10px $gray-300; + } + } + } + } + + > tfoot > tr > th { + padding: 0.75rem; + text-align: left; + background-color: $o-list-footer-bg-color; + position: sticky; + bottom: 0; + + &.col-total { + right: 0; + border-left-width: 1px; + border-left-color: $gray-300; + border-left-style: solid; + } + } + } +} diff --git a/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/x2many_2d_matrix_field.xml b/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/x2many_2d_matrix_field.xml new file mode 100644 index 000000000000..1f908861361b --- /dev/null +++ b/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_field/x2many_2d_matrix_field.xml @@ -0,0 +1,16 @@ + + + +
+ +
+
+
diff --git a/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_renderer/x2many_2d_matrix_renderer.esm.js b/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_renderer/x2many_2d_matrix_renderer.esm.js new file mode 100644 index 000000000000..30756a926ad3 --- /dev/null +++ b/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_renderer/x2many_2d_matrix_renderer.esm.js @@ -0,0 +1,147 @@ +/** @odoo-module **/ + +import {Component, onWillUpdateProps} from "@odoo/owl"; +import {registry} from "@web/core/registry"; + +export class X2Many2DMatrixRenderer extends Component { + setup() { + this.ValueFieldComponent = this._getValueFieldComponent(); + this.columns = this._getColumns(); + this.rows = this._getRows(); + this.matrix = this._getMatrix(); + + onWillUpdateProps((newProps) => { + this.columns = this._getColumns(newProps.list.records); + this.rows = this._getRows(newProps.list.records); + this.matrix = this._getMatrix(newProps.list.records); + }); + } + + _getColumns(records = this.list.records) { + const columns = []; + records.forEach((record) => { + const column = { + value: record.data[this.matrixFields.x], + text: record.data[this.matrixFields.x], + }; + if (record.fields[this.matrixFields.x].type === "many2one") { + column.text = column.value[1]; + column.value = column.value[0]; + } + if (columns.findIndex((c) => c.value === column.value) !== -1) return; + columns.push(column); + }); + return columns; + } + + _getRows(records = this.list.records) { + const rows = []; + records.forEach((record) => { + const row = { + value: record.data[this.matrixFields.y], + text: record.data[this.matrixFields.y], + }; + if (record.fields[this.matrixFields.y].type === "many2one") { + row.text = row.value[1]; + row.value = row.value[0]; + } + if (rows.findIndex((r) => r.value === row.value) !== -1) return; + rows.push(row); + }); + return rows; + } + + _getPointOfRecord(record) { + let xValue = record.data[this.matrixFields.x]; + if (record.fields[this.matrixFields.x].type === "many2one") { + xValue = xValue[0]; + } + let yValue = record.data[this.matrixFields.y]; + if (record.fields[this.matrixFields.y].type === "many2one") { + yValue = yValue[0]; + } + + const x = this.columns.findIndex((c) => c.value === xValue); + const y = this.rows.findIndex((r) => r.value === yValue); + return {x, y}; + } + + _getMatrix(records = this.list.records) { + const matrix = this.rows.map(() => + new Array(this.columns.length).fill(null).map(() => { + return {value: 0, records: []}; + }) + ); + records.forEach((record) => { + const value = record.data[this.matrixFields.value]; + const {x, y} = this._getPointOfRecord(record); + matrix[y][x].value += value; + matrix[y][x].records.push(record); + }); + return matrix; + } + + get list() { + return this.props.list; + } + + get matrixFields() { + return this.props.matrixFields; + } + + _getValueFieldComponent() { + const field = this.list.activeFields[this.matrixFields.value]; + if (!field.widget) { + return this.list.activeFields[this.matrixFields.value].FieldComponent; + } + return registry.category("fields").get(field.widget); + } + + _aggregateRow(row) { + const y = this.rows.findIndex((r) => r.value === row); + return this.matrix[y].map((r) => r.value).reduce((aggr, x) => aggr + x); + } + + _aggregateColumn(column) { + const x = this.columns.findIndex((c) => c.value === column); + return this.matrix + .map((r) => r[x]) + .map((r) => r.value) + .reduce((aggr, y) => aggr + y); + } + + _aggregateAll() { + return this.matrix + .map((r) => r.map((x) => x.value).reduce((aggr, x) => aggr + x)) + .reduce((aggr, y) => aggr + y); + } + + update(x, y, value) { + this.matrix[y][x].value = value; + const xFieldValue = this.columns[x].value; + const yFieldValue = this.rows[y].value; + + this.props.onUpdate(xFieldValue, yFieldValue, value); + } + + getValueFieldProps(column, row) { + const x = this.columns.findIndex((c) => c.value === column); + const y = this.rows.findIndex((r) => r.value === row); + return { + value: this.matrix[y][x].value, + update: (value) => this.update(x, y, value), + readonly: this.props.readonly, + }; + } +} + +X2Many2DMatrixRenderer.template = "web_widget_x2many_2d_matrix.X2Many2DMatrixRenderer"; +X2Many2DMatrixRenderer.props = { + list: Object, + matrixFields: Object, + setDirty: Function, + onUpdate: Function, + readonly: Boolean, + showRowTotals: Boolean, + showColumnTotals: Boolean, +}; diff --git a/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_renderer/x2many_2d_matrix_renderer.xml b/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_renderer/x2many_2d_matrix_renderer.xml new file mode 100644 index 000000000000..1c2fe9c078b7 --- /dev/null +++ b/web_widget_x2many_2d_matrix/static/src/components/x2many_2d_matrix_renderer/x2many_2d_matrix_renderer.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+ + + + +
+
+ Nothing to display. +
+
+