Browse Source

[MIG] web_widget_x2many_2d_matrix: Migration to 12.0

pull/1106/head
Alexey Pelykh 6 years ago
committed by Jairo Llopis
parent
commit
95b01b24eb
  1. 68
      web_widget_x2many_2d_matrix/README.rst
  2. 20
      web_widget_x2many_2d_matrix/__init__.py
  3. 28
      web_widget_x2many_2d_matrix/__manifest__.py
  4. 8
      web_widget_x2many_2d_matrix/readme/CONTRIBUTORS.rst
  5. 23
      web_widget_x2many_2d_matrix/readme/DESCRIPTION.rst
  6. 14
      web_widget_x2many_2d_matrix/readme/ROADMAP.rst
  7. 92
      web_widget_x2many_2d_matrix/readme/USAGE.rst
  8. 568
      web_widget_x2many_2d_matrix/static/description/index.html
  9. 27
      web_widget_x2many_2d_matrix/views/assets.xml

68
web_widget_x2many_2d_matrix/README.rst

@ -1,11 +1,30 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
===========================
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-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github
:target: https://github.com/OCA/web/tree/12.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-12-0/web-12-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/12.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
@ -30,6 +49,11 @@ 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
=====
@ -71,10 +95,6 @@ show_column_totals
If field_value is a numeric field, it indicates if you want to calculate
column totals. True by default
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/162/11.0
Example
=======
@ -151,16 +171,25 @@ Known issues / Roadmap
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/web/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing a detailed and welcomed feedback.
Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/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 <https://github.com/OCA/web/issues/new?body=module:%20web_widget_x2many_2d_matrix%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Therp BV
* Tecnativa
* Camptocamp
Contributors
------------
~~~~~~~~~~~~
* Holger Brunn <hbrunn@therp.nl>
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
@ -169,18 +198,21 @@ Contributors
* Timon Tschanz <timon.tschanz@camptocamp.com>
* Jairo Llopis <jairo.llopis@tecnativa.com>
* Dennis Sluijk <d.sluijk@onestein.nl>
* Alexey Pelykh <alexey.pelykh@brainbeanapps.com>
Maintainers
~~~~~~~~~~~
Maintainer
----------
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
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.
To contribute to this module, please visit https://odoo-community.org.
This module is part of the `OCA/web <https://github.com/OCA/web/tree/12.0/web_widget_x2many_2d_matrix>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

20
web_widget_x2many_2d_matrix/__init__.py

@ -1,19 +1 @@
##############################################################################
#
# OpenERP, Open Source Management Solution
# This module copyright (C) 2015 Therp BV <http://therp.nl>.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

28
web_widget_x2many_2d_matrix/__manifest__.py

@ -3,21 +3,23 @@
# Copyright 2018 Simone Orsi <simone.orsi@camptocamp.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "2D matrix for x2many fields",
"version": "11.0.1.1.1",
"author": "Therp BV, "
"Tecnativa, "
"Camptocamp, "
"Odoo Community Association (OCA)",
"website": "https://github.com/OCA/web",
"license": "AGPL-3",
"category": "Hidden/Dependency",
"summary": "Show list fields as a matrix",
"depends": [
'name': '2D matrix for x2many fields',
'version': '12.0.1.0.0',
'author': (
'Therp BV, '
'Tecnativa, '
'Camptocamp, '
'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": [
'data': [
'views/assets.xml',
],
"installable": True,
'installable': True,
}

8
web_widget_x2many_2d_matrix/readme/CONTRIBUTORS.rst

@ -0,0 +1,8 @@
* Holger Brunn <hbrunn@therp.nl>
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
* Artem Kostyuk <a.kostyuk@mobilunity.com>
* Simone Orsi <simone.orsi@camptocamp.com>
* Timon Tschanz <timon.tschanz@camptocamp.com>
* Jairo Llopis <jairo.llopis@tecnativa.com>
* Dennis Sluijk <d.sluijk@onestein.nl>
* Alexey Pelykh <alexey.pelykh@brainbeanapps.com>

23
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:: /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.

14
web_widget_x2many_2d_matrix/readme/ROADMAP.rst

@ -0,0 +1,14 @@
* 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.

92
web_widget_x2many_2d_matrix/readme/USAGE.rst

@ -0,0 +1,92 @@
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:
.. code-block:: xml
<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:
.. 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
<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>

568
web_widget_x2many_2d_matrix/static/description/index.html

@ -0,0 +1,568 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
<title>2D matrix for x2many fields</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="d-matrix-for-x2many-fields">
<h1 class="title">2D matrix for x2many fields</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/web/tree/12.0/web_widget_x2many_2d_matrix"><img alt="OCA/web" src="https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/web-12-0/web-12-0-web_widget_x2many_2d_matrix"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/162/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This module allows to show an x2many field with 3-tuples
($x_value, $y_value, $value) in a table</p>
<table border="1" class="docutils">
<colgroup>
<col width="30%" />
<col width="35%" />
<col width="35%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">&nbsp;</th>
<th class="head">$x_value1</th>
<th class="head">$x_value2</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>$y_value1</td>
<td>$value(1/1)</td>
<td>$value(2/1)</td>
</tr>
<tr><td>$y_value2</td>
<td>$value(1/2)</td>
<td>$value(2/2)</td>
</tr>
</tbody>
</table>
<p>where <cite>value(n/n)</cite> is editable.</p>
<p>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:</p>
<img alt="Screenshot" src="/web_widget_x2many_2d_matrix/static/description/screenshot.png" />
<p>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.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="id1">Usage</a></li>
<li><a class="reference internal" href="#example" id="id2">Example</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="id3">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id4">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id5">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id6">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id7">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id8">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id1">Usage</a></h1>
<p>Use this widget by saying:</p>
<pre class="literal-block">
&lt;field name=&quot;my_field&quot; widget=&quot;x2many_2d_matrix&quot; /&gt;
</pre>
<p>This assumes that my_field refers to a model with the fields <cite>x</cite>, <cite>y</cite> and
<cite>value</cite>. If your fields are named differently, pass the correct names as
attributes:</p>
<pre class="code xml literal-block">
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;my_field&quot;</span> <span class="na">widget=</span><span class="s">&quot;x2many_2d_matrix&quot;</span> <span class="na">field_x_axis=</span><span class="s">&quot;my_field1&quot;</span> <span class="na">field_y_axis=</span><span class="s">&quot;my_field2&quot;</span> <span class="na">field_value=</span><span class="s">&quot;my_field3&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;tree&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;my_field&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;my_field1&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;my_field2&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;my_field3&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/tree&gt;</span>
<span class="nt">&lt;/field&gt;</span>
</pre>
<p>You can pass the following parameters:</p>
<dl class="docutils">
<dt>field_x_axis</dt>
<dd>The field that indicates the x value of a point</dd>
<dt>field_y_axis</dt>
<dd>The field that indicates the y value of a point</dd>
<dt>field_label_x_axis</dt>
<dd>Use another field to display in the table header</dd>
<dt>field_label_y_axis</dt>
<dd>Use another field to display in the table header</dd>
<dt>field_value</dt>
<dd>Show this field as value</dd>
<dt>show_row_totals</dt>
<dd>If field_value is a numeric field, it indicates if you want to calculate
row totals. True by default</dd>
<dt>show_column_totals</dt>
<dd>If field_value is a numeric field, it indicates if you want to calculate
column totals. True by default</dd>
</dl>
</div>
<div class="section" id="example">
<h1><a class="toc-backref" href="#id2">Example</a></h1>
<p>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 <tt class="docutils literal">project.task</tt> as our
data model and point to it from our wizard. The crucial part is that we fill
the field in the default function:</p>
<pre class="code python literal-block">
<span class="kn">from</span> <span class="nn">odoo</span> <span class="kn">import</span> <span class="n">fields</span><span class="p">,</span> <span class="n">models</span>
<span class="k">class</span> <span class="nc">MyWizard</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">TransientModel</span><span class="p">):</span>
<span class="n">_name</span> <span class="o">=</span> <span class="s1">'my.wizard'</span>
<span class="k">def</span> <span class="nf">_default_task_ids</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># your list of project should come from the context, some selection</span>
<span class="c1"># in a previous wizard or wherever else</span>
<span class="n">projects</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="p">[</span><span class="s1">'project.project'</span><span class="p">]</span><span class="o">.</span><span class="n">browse</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span>
<span class="c1"># same with users</span>
<span class="n">users</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="p">[</span><span class="s1">'res.users'</span><span class="p">]</span><span class="o">.</span><span class="n">browse</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span>
<span class="k">return</span> <span class="p">[</span>
<span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">{</span>
<span class="s1">'name'</span><span class="p">:</span> <span class="s1">'Sample task name'</span><span class="p">,</span>
<span class="s1">'project_id'</span><span class="p">:</span> <span class="n">p</span><span class="o">.</span><span class="n">id</span><span class="p">,</span>
<span class="s1">'user_id'</span><span class="p">:</span> <span class="n">u</span><span class="o">.</span><span class="n">id</span><span class="p">,</span>
<span class="s1">'planned_hours'</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s1">'message_needaction'</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
<span class="s1">'date_deadline'</span><span class="p">:</span> <span class="n">fields</span><span class="o">.</span><span class="n">Date</span><span class="o">.</span><span class="n">today</span><span class="p">(),</span>
<span class="p">})</span>
<span class="c1"># if the project doesn't have a task for the user,</span>
<span class="c1"># create a new one</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">task_ids</span><span class="o">.</span><span class="n">filtered</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">user_id</span> <span class="o">==</span> <span class="n">u</span><span class="p">)</span> <span class="k">else</span>
<span class="c1"># otherwise, return the task</span>
<span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">task_ids</span><span class="o">.</span><span class="n">filtered</span><span class="p">(</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">user_id</span> <span class="o">==</span> <span class="n">u</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">projects</span>
<span class="k">for</span> <span class="n">u</span> <span class="ow">in</span> <span class="n">users</span>
<span class="p">]</span>
<span class="n">task_ids</span> <span class="o">=</span> <span class="n">fields</span><span class="o">.</span><span class="n">Many2many</span><span class="p">(</span><span class="s1">'project.task'</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">_default_task_ids</span><span class="p">)</span>
</pre>
<p>Now in our wizard, we can use:</p>
<pre class="code xml literal-block">
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;task_ids&quot;</span> <span class="na">widget=</span><span class="s">&quot;x2many_2d_matrix&quot;</span> <span class="na">field_x_axis=</span><span class="s">&quot;project_id&quot;</span> <span class="na">field_y_axis=</span><span class="s">&quot;user_id&quot;</span> <span class="na">field_value=</span><span class="s">&quot;planned_hours&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;tree&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;task_ids&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;project_id&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;user_id&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;planned_hours&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/tree&gt;</span>
<span class="nt">&lt;/field&gt;</span>
</pre>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#id3">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>Support extra attributes on each field cell via <cite>field_extra_attrs</cite> param.
We could set a cell as not editable, required or readonly for instance.
The <cite>readonly</cite> case will also give the ability
to click on m2o to open related records.</li>
<li>Support limit total records in the matrix. Ref: <a class="reference external" href="https://github.com/OCA/web/issues/901">https://github.com/OCA/web/issues/901</a></li>
<li>Support cell traversal through keyboard arrows.</li>
<li>Entering the widget from behind by pressing <tt class="docutils literal">Shift+TAB</tt> in your keyboard
will enter into the 1st cell until <a class="reference external" href="https://github.com/odoo/odoo/pull/26490">https://github.com/odoo/odoo/pull/26490</a>
is merged.</li>
<li>Support extra invisible fields inside each cell.</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id4">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/web/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/web/issues/new?body=module:%20web_widget_x2many_2d_matrix%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id5">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id6">Authors</a></h2>
<ul class="simple">
<li>Therp BV</li>
<li>Tecnativa</li>
<li>Camptocamp</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id7">Contributors</a></h2>
<ul class="simple">
<li>Holger Brunn &lt;<a class="reference external" href="mailto:hbrunn&#64;therp.nl">hbrunn&#64;therp.nl</a>&gt;</li>
<li>Pedro M. Baeza &lt;<a class="reference external" href="mailto:pedro.baeza&#64;tecnativa.com">pedro.baeza&#64;tecnativa.com</a>&gt;</li>
<li>Artem Kostyuk &lt;<a class="reference external" href="mailto:a.kostyuk&#64;mobilunity.com">a.kostyuk&#64;mobilunity.com</a>&gt;</li>
<li>Simone Orsi &lt;<a class="reference external" href="mailto:simone.orsi&#64;camptocamp.com">simone.orsi&#64;camptocamp.com</a>&gt;</li>
<li>Timon Tschanz &lt;<a class="reference external" href="mailto:timon.tschanz&#64;camptocamp.com">timon.tschanz&#64;camptocamp.com</a>&gt;</li>
<li>Jairo Llopis &lt;<a class="reference external" href="mailto:jairo.llopis&#64;tecnativa.com">jairo.llopis&#64;tecnativa.com</a>&gt;</li>
<li>Dennis Sluijk &lt;<a class="reference external" href="mailto:d.sluijk&#64;onestein.nl">d.sluijk&#64;onestein.nl</a>&gt;</li>
<li>Alexey Pelykh &lt;<a class="reference external" href="mailto:alexey.pelykh&#64;brainbeanapps.com">alexey.pelykh&#64;brainbeanapps.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id8">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>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.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/web/tree/12.0/web_widget_x2many_2d_matrix">OCA/web</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

27
web_widget_x2many_2d_matrix/views/assets.xml

@ -1,13 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<template id="assets_backend" name="web_widget_x2many_2d_matrix assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js" />
<script type="text/javascript" src="/web_widget_x2many_2d_matrix/static/src/js/widget_x2many_2d_matrix.js" />
<script type="text/javascript" src="/web_widget_x2many_2d_matrix/static/src/js/abstract_view_matrix_limit_extend.js" />
<link rel="stylesheet" href="/web_widget_x2many_2d_matrix/static/src/css/web_widget_x2many_2d_matrix.css"/>
</xpath>
</template>
</data>
</openerp>
<odoo>
<!--
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-->
<template id="assets_backend" name="web_widget_x2many_2d_matrix assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js" />
<script type="text/javascript" src="/web_widget_x2many_2d_matrix/static/src/js/widget_x2many_2d_matrix.js" />
<script type="text/javascript" src="/web_widget_x2many_2d_matrix/static/src/js/abstract_view_matrix_limit_extend.js" />
<link rel="stylesheet" href="/web_widget_x2many_2d_matrix/static/src/css/web_widget_x2many_2d_matrix.css"/>
</xpath>
</template>
</odoo>
Loading…
Cancel
Save