From c38c70e0f3a6405e3768ce5fb70d8fab6bea362a Mon Sep 17 00:00:00 2001 From: Alexey Pelykh Date: Thu, 6 Dec 2018 14:25:47 +0200 Subject: [PATCH] [FIX] web_widget_x2many_2d_matrix: _renderBodyCell + _renderAggregateColCells --- web_widget_x2many_2d_matrix/README.rst | 18 ++- web_widget_x2many_2d_matrix/__manifest__.py | 3 +- .../readme/DESCRIPTION.rst | 2 +- .../readme/HISTORY.rst | 11 ++ .../static/description/index.html | 57 ++++++--- .../static/src/js/2d_matrix_renderer.js | 108 +++++++++++------- .../static/src/js/widget_x2many_2d_matrix.js | 12 +- 7 files changed, 148 insertions(+), 63 deletions(-) create mode 100644 web_widget_x2many_2d_matrix/readme/HISTORY.rst diff --git a/web_widget_x2many_2d_matrix/README.rst b/web_widget_x2many_2d_matrix/README.rst index 1372c625a..c0693fcf4 100644 --- a/web_widget_x2many_2d_matrix/README.rst +++ b/web_widget_x2many_2d_matrix/README.rst @@ -42,7 +42,7 @@ 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/web_widget_x2many_2d_matrix/static/description/screenshot.png +.. 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 @@ -168,6 +168,21 @@ Known issues / Roadmap * Support extra invisible fields inside each cell. +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 =========== @@ -187,6 +202,7 @@ Authors * Therp BV * Tecnativa * Camptocamp +* Brainbean Apps Contributors ~~~~~~~~~~~~ diff --git a/web_widget_x2many_2d_matrix/__manifest__.py b/web_widget_x2many_2d_matrix/__manifest__.py index bfee53ec3..3299e66b7 100644 --- a/web_widget_x2many_2d_matrix/__manifest__.py +++ b/web_widget_x2many_2d_matrix/__manifest__.py @@ -4,11 +4,12 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { 'name': '2D matrix for x2many fields', - 'version': '12.0.1.0.0', + 'version': '12.0.1.0.1', 'author': ( 'Therp BV, ' 'Tecnativa, ' 'Camptocamp, ' + 'Brainbean Apps, ' 'Odoo Community Association (OCA)' ), 'website': 'https://github.com/OCA/web', diff --git a/web_widget_x2many_2d_matrix/readme/DESCRIPTION.rst b/web_widget_x2many_2d_matrix/readme/DESCRIPTION.rst index a84da8005..d3f10cae8 100644 --- a/web_widget_x2many_2d_matrix/readme/DESCRIPTION.rst +++ b/web_widget_x2many_2d_matrix/readme/DESCRIPTION.rst @@ -15,7 +15,7 @@ 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 +.. 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 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 000000000..8bad8c46c --- /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/static/description/index.html b/web_widget_x2many_2d_matrix/static/description/index.html index bd5775f28..1be53a2a7 100644 --- a/web_widget_x2many_2d_matrix/static/description/index.html +++ b/web_widget_x2many_2d_matrix/static/description/index.html @@ -397,29 +397,34 @@ ul.auto-toc {

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 +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

+

Usage

Use this widget by saying:

 <field name="my_field" widget="x2many_2d_matrix" />
@@ -457,7 +462,7 @@ row totals. True by default
 column totals. True by default
 
 
-

Example

+

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 @@ -509,7 +514,7 @@ the field in the default function:

-

Known issues / Roadmap

+

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. @@ -523,8 +528,25 @@ is merged.
  • Support extra invisible fields inside each cell.
+
+

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

+

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 @@ -532,17 +554,18 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Therp BV
  • Tecnativa
  • Camptocamp
  • +
  • Brainbean Apps
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association

OCA, or the Odoo Community Association, is a nonprofit organization whose diff --git a/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js b/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js index ac627e44c..30808ae1b 100644 --- a/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js +++ b/web_widget_x2many_2d_matrix/static/src/js/2d_matrix_renderer.js @@ -1,23 +1,25 @@ /* Copyright 2018 Simone Orsi + * Copyright 2018 Brainbean Apps * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (require) { "use strict"; - // Heavily inspired by Odoo's `ListRenderer` var BasicRenderer = require('web.BasicRenderer'); var config = require('web.config'); var core = require('web.core'); var field_utils = require('web.field_utils'); var _t = core._t; + var FIELD_CLASSES = { - // Copied from ListRenderer float: 'o_list_number', integer: 'o_list_number', monetary: 'o_list_number', text: 'o_list_text', }; + // X2Many2dMatrixRenderer is heavily inspired by Odoo's ListRenderer + // and is reusing portions of code from list_renderer.js var X2Many2dMatrixRenderer = BasicRenderer.extend({ /** @@ -53,8 +55,11 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ _renderView: function () { var self = this; + this.$el + .removeClass('table-responsive') + .empty(); + // Display a nice message if there's no data to display - this.$el.empty(); if (!self.rows.length) { var $alert = $('

', {'class': 'alert alert-info'}); $alert.text(_t('Sorry no matrix data to display.')); @@ -170,7 +175,10 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ * @returns {String} a string with the generated html. */ _renderRows: function () { - return _.map(this.rows, this._renderRow.bind(this)); + return _.map(this.rows, function (row) { + row.attrs.name = this.matrix_data.field_value; + return this._renderRow(row); + }.bind(this)); }, /** @@ -187,11 +195,11 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ var $tr = $('', {class: 'o_data_row'}), _data = _.without(row.data, undefined); $tr = $tr.append(this._renderLabelCell(_data[0])); - var $cells = _.map(this.columns, function (node, index) { + var $cells = _.map(this.columns, function (column, index) { var record = row.data[index]; // Make the widget use our field value for each cell - node.attrs.name = this.matrix_data.field_value; - return this._renderBodyCell(record, node, index, {mode:''}); + column.attrs.name = this.matrix_data.field_value; + return this._renderBodyCell(record, column, index, {mode:''}); }.bind(this)); $tr = $tr.append($cells); if (row.aggregate) { @@ -227,8 +235,8 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ * @returns {jQueryElement} The rendered cell. */ _renderAggregateRowCell: function (row) { - var $cell = $('', {class: 'row-total text-right'}); - this._apply_aggregate_value($cell, row.aggregate); + var $cell = $('', {class: 'row-total'}); + this.applyAggregateValue($cell, row); return $cell; }, @@ -246,9 +254,7 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ */ _renderBodyCell: function (record, node, colIndex, options) { var tdClassName = 'o_data_cell'; - if (node.tag === 'button') { - tdClassName += ' o_list_button'; - } else if (node.tag === 'field') { + if (node.tag === 'field') { var typeClass = FIELD_CLASSES[ this.state.fields[node.attrs.name].type ]; @@ -259,11 +265,14 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ tdClassName += ' o_' + node.attrs.widget + '_cell'; } } + // TODO roadmap: here we should collect possible extra params // the user might want to attach to each single cell. + var $td = $('', { 'class': tdClassName, }); + if (_.isUndefined(record)) { // Without record, nothing elese to do return $td; @@ -272,6 +281,7 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ 'data-form-id': record.id, 'data-id': record.data.id, }); + // We register modifiers on the element so that it gets // the correct modifiers classes (for styling) var modifiers = this._registerModifiers( @@ -286,13 +296,28 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ if (modifiers.invisible && !(options && options.renderInvisible)) { return $td; } + // Enforce mode of the parent options.mode = this.getParent().mode; - var widget = this._renderFieldWidget( - node, record, _.pick(options, 'mode') - ); - this._handleAttributes(widget.$el, node); - return $td.append(widget.$el); + + if (node.tag === 'widget') { + return $td.append(this._renderWidget(record, node)); + } + if (node.attrs.widget || (options && (options.renderWidgets || options.mode === 'edit'))) { + var $el = this._renderFieldWidget(node, record, _.pick(options, 'mode')); + this._handleAttributes($el, node); + return $td.append($el); + } + var name = node.attrs.name; + var field = this.state.fields[name]; + var value = record.data[name]; + var formattedValue = field_utils.format[field.type](value, field, { + data: record.data, + escape: true, + isPassword: 'password' in node.attrs, + }); + this._handleAttributes($td, node); + return $td.html(formattedValue); }, /** @@ -325,8 +350,8 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ return; } - var $cell = $('', {class: 'col-total text-right'}); - this._apply_aggregate_value($cell, this.total); + var $cell = $('', {class: 'col-total'}); + this.applyAggregateValue($cell, this.total); return $cell; }, @@ -338,10 +363,14 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ */ _renderAggregateColCells: function () { var self = this; + return _.map(this.columns, function (column) { - var $cell = $('', {class: 'col-total text-right'}); + var $cell = $(''); + if (config.debug) { + $cell.addClass(column.attrs.name); + } if (column.aggregate) { - self._apply_aggregate_value($cell, column.aggregate); + self.applyAggregateValue($cell, column) } return $cell; }); @@ -367,15 +396,16 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ return; } this.total = { - fname: fname, - ftype: type, - help: _t('Sum Total'), - value: 0, + attrs: { + name: fname, + }, + aggregate: { + help: _t('Sum Total'), + value: 0, + }, }; _.each(this.columns, function (column, index) { column.aggregate = { - fname: fname, - ftype: type, help: _t('Sum'), value: 0, }; @@ -451,8 +481,6 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ } _.each(this.rows, function (row) { row.aggregate = { - fname: fname, - ftype: type, help: _t('Sum'), value: 0, }; @@ -475,17 +503,19 @@ odoo.define('web_widget_x2many_2d_matrix.X2Many2dMatrixRenderer', function (requ * @param {jQueryElement} $cell * The Cell where the aggregate should be added. * - * @param {Object} aggregate - * The object which contains the information about the aggregate value + * @param {Object} axis + * The object which contains the information about the aggregate value axis */ - _apply_aggregate_value: function ($cell, aggregate) { - var field = this.state.fields[aggregate.fname], - formatter = field_utils.format[field.type]; - var formattedValue = formatter( - aggregate.value, field, {escape: true} - ); - $cell.addClass('total').attr('title', aggregate.help) - .html(formattedValue); + applyAggregateValue: function ($cell, axis) { + var field = this.state.fields[axis.attrs.name]; + var value = axis.aggregate.value; + var help = axis.aggregate.help; + var formatFunc = field_utils.format[axis.attrs.widget]; + if (!formatFunc) { + formatFunc = field_utils.format[field.type]; + } + var formattedValue = formatFunc(value, field, { escape: true }); + $cell.addClass('o_list_number').attr('title', help).html(formattedValue); }, /** diff --git a/web_widget_x2many_2d_matrix/static/src/js/widget_x2many_2d_matrix.js b/web_widget_x2many_2d_matrix/static/src/js/widget_x2many_2d_matrix.js index addf7cd40..bdaead56a 100644 --- a/web_widget_x2many_2d_matrix/static/src/js/widget_x2many_2d_matrix.js +++ b/web_widget_x2many_2d_matrix/static/src/js/widget_x2many_2d_matrix.js @@ -56,9 +56,6 @@ odoo.define('web_widget_x2many_2d_matrix.widget', function (require) { node[property]; } } - // And this? - this.field_editability = - node.field_editability || this.field_editability; this.show_row_totals = this.parse_boolean(node.show_row_totals || '1'); this.show_column_totals = @@ -138,7 +135,14 @@ odoo.define('web_widget_x2many_2d_matrix.widget', function (require) { _make_row: function (y) { var self = this; // Use object so that we can attach more data if needed - var row = {'data': []}; + var row = { + 'tag': 'field', + 'attrs': { + 'name': this.field_y_axis, + 'string': y, + }, + 'data': [], + }; $.each(self.by_x_axis, function (x) { row.data.push(self.by_y_axis[y][x]); });