Browse Source

Merge pull request #1223 from Eficent/12.0-mig-web_tree_dynamic_colored_field

[12.0][MIG] web_tree_dynamic_colored_field
pull/1294/head
Jordi Ballester Alomar 6 years ago
committed by GitHub
parent
commit
e84b5f499e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 133
      web_tree_dynamic_colored_field/README.rst
  2. 1
      web_tree_dynamic_colored_field/__init__.py
  3. 19
      web_tree_dynamic_colored_field/__manifest__.py
  4. 24
      web_tree_dynamic_colored_field/demo/res_users.xml
  5. 14
      web_tree_dynamic_colored_field/i18n/web_tree_dynamic_colored_field.pot
  6. 4
      web_tree_dynamic_colored_field/readme/CONTRIBUTORS.rst
  7. 15
      web_tree_dynamic_colored_field/readme/DESCRIPTION.rst
  8. 67
      web_tree_dynamic_colored_field/readme/USAGE.rst
  9. BIN
      web_tree_dynamic_colored_field/static/description/icon.png
  10. 130
      web_tree_dynamic_colored_field/static/src/js/web_tree_dynamic_colored_field.js
  11. 8
      web_tree_dynamic_colored_field/views/web_tree_dynamic_colored_field.xml

133
web_tree_dynamic_colored_field/README.rst

@ -0,0 +1,133 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: https://www.gnu.org/licenses/agpl
:alt: License: AGPL-3
============================
Colorize field in tree views
============================
This module aims to add support for dynamically coloring fields in tree view
according to data in the record.
It provides attributes on fields with the similar syntax as the ``colors`` attribute
in tree tags.
Further, it provides a ``color_field`` attribute on tree tags's ``colors`` to use
a field's value as color.
Features
========
* Add attribute ``bg_color`` on field's ``options`` to color background of a cell in tree view
* Add attribute ``fg_color`` on field's ``options`` to change text color of a cell in tree view
* Add attribute ``color_field`` on the tree element's ``colors`` to use as color
Usage
=====
* In the tree view declaration, put ``options='{"bg_color": "red: customer==True"}`` attribute in the ``field`` tag::
...
<field name="arch" type="xml">
<tree string="View name">
...
<field name="name" options='{"bg_color": "red: customer == True"}'/>
...
</tree>
</field>
...
With this example, column which renders 'name' field will have its background colored in red.
* In the tree view declaration, put ``options='{"fg_color": "white:customer == True"}'`` attribute in the ``field`` tag::
...
<field name="arch" type="xml">
<tree string="View name">
...
<field name="name" options='{"fg_color": "white:customer == True"}'/>
...
</tree>
</field>
...
With this example, column which renders 'name' field will have its text colored in white on a customer records.
* In the tree view declaration, use ``options='"color_field": "my_color"'`` attribute in the ``tree`` tag::
...
<field name="arch" type="xml">
<tree string="View name" colors="color_field: my_color" >
...
<field name="my_color" invisible="1"/>
...
</tree>
</field>
...
* If you want to use more than one color, you can split the attributes using ';':
.. code::
options='{"fg_color": "red:red_color == True; green:green_color == True"}'
Example:
.. code:: xml
...
<field name="arch" type="xml">
<tree string="View name">
...
<field name="name" options='{"fg_color": "red:red_color == True; green:green_color == True"}'/>
...
</tree>
</field>
...
With this example, the content of the field named `my_color` will be used to
populate the `my_color` CSS value. Use a function field to return whichever
color you want depending on the other record values. Note that this
overrides the rest of `colors` attributes, and that you need the tree
to load your field in the first place by adding it as invisible field.
**Note that you should always use single quotes for fields' ``options`` and wrap nested values in double quotes since ``options`` is a JSON object.**
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 detailed and welcomed feedback.
Credits
=======
Images
------
* Odoo Community Association: `Icon <https://odoo-community.org/logo.png>`_.
Contributors
------------
* Damien Crier <damien.crier@camptocamp.com>
* Holger Brunn <hbrunn@therp.nl>
* Artem Kostyuk <a.kostyuk@mobilunity.com>
* Guewen Baconnier <guewen.baconnier@camptocamp.com>
Maintainer
----------
.. 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.

1
web_tree_dynamic_colored_field/__init__.py

@ -0,0 +1 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

19
web_tree_dynamic_colored_field/__manifest__.py

@ -0,0 +1,19 @@
# Copyright 2015-2018 Camptocamp SA, Damien Crier
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'Colorize field in tree views',
'summary': 'Allows you to dynamically color fields on tree views',
'category': 'Hidden/Dependency',
'version': '12.0.1.0.0',
'depends': ['web'],
'author': "Camptocamp, Therp BV, Odoo Community Association (OCA)",
'license': 'AGPL-3',
'website': 'https://github.com/OCA/web',
'demo': [
"demo/res_users.xml",
],
'data': [
'views/web_tree_dynamic_colored_field.xml',
],
'installable': True,
}

24
web_tree_dynamic_colored_field/demo/res_users.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="view_users_tree" model="ir.ui.view">
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_tree" />
<field name="arch" type="xml">
<tree position="attributes">
<attribute name="colors">color_field: lang</attribute>
</tree>
<field name="login_date" position="attributes">
<attribute name="options">{
"bg_color": "#9e1635: login_date == False",
"fg_color": "white: login_date == False"
}</attribute>
</field>
<field name="name" position="attributes">
<attribute name="options"> {
"bg_color": "blue; #653b5b: login == 'admin'",
"fg_color": "white"
}</attribute>
</field>
</field>
</record>
</odoo>

14
web_tree_dynamic_colored_field/i18n/web_tree_dynamic_colored_field.pot

@ -0,0 +1,14 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.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"

4
web_tree_dynamic_colored_field/readme/CONTRIBUTORS.rst

@ -0,0 +1,4 @@
* Damien Crier <damien.crier@camptocamp.com>
* Holger Brunn <hbrunn@therp.nl>
* Artem Kostyuk <a.kostyuk@mobilunity.com>
* Guewen Baconnier <guewen.baconnier@camptocamp.com>

15
web_tree_dynamic_colored_field/readme/DESCRIPTION.rst

@ -0,0 +1,15 @@
This module aims to add support for dynamically coloring fields in tree view
according to data in the record.
It provides attributes on fields with the similar syntax as the ``colors`` attribute
in tree tags.
Further, it provides a ``color_field`` attribute on tree tags's ``colors`` to use
a field's value as color.
Features
========
* Add attribute ``bg_color`` on field's ``options`` to color background of a cell in tree view
* Add attribute ``fg_color`` on field's ``options`` to change text color of a cell in tree view
* Add attribute ``color_field`` on the tree element's ``colors`` to use as color

67
web_tree_dynamic_colored_field/readme/USAGE.rst

@ -0,0 +1,67 @@
* In the tree view declaration, put ``options='{"bg_color": "red: customer==True"}`` attribute in the ``field`` tag::
...
<field name="arch" type="xml">
<tree string="View name">
...
<field name="name" options='{"bg_color": "red: customer == True"}'/>
...
</tree>
</field>
...
With this example, column which renders 'name' field will have its background colored in red.
* In the tree view declaration, put ``options='{"fg_color": "white:customer == True"}'`` attribute in the ``field`` tag::
...
<field name="arch" type="xml">
<tree string="View name">
...
<field name="name" options='{"fg_color": "white:customer == True"}'/>
...
</tree>
</field>
...
With this example, column which renders 'name' field will have its text colored in white on a customer records.
* In the tree view declaration, use ``options='"color_field": "my_color"'`` attribute in the ``tree`` tag::
...
<field name="arch" type="xml">
<tree string="View name" colors="color_field: my_color" >
...
<field name="my_color" invisible="1"/>
...
</tree>
</field>
...
* If you want to use more than one color, you can split the attributes using ';':
.. code::
options='{"fg_color": "red:red_color == True; green:green_color == True"}'
Example:
.. code:: xml
...
<field name="arch" type="xml">
<tree string="View name">
...
<field name="name" options='{"fg_color": "red:red_color == True; green:green_color == True"}'/>
...
</tree>
</field>
...
With this example, the content of the field named `my_color` will be used to
populate the `my_color` CSS value. Use a function field to return whichever
color you want depending on the other record values. Note that this
overrides the rest of `colors` attributes, and that you need the tree
to load your field in the first place by adding it as invisible field.
**Note that you should always use single quotes for fields' ``options`` and wrap nested values in double quotes since ``options`` is a JSON object.**

BIN
web_tree_dynamic_colored_field/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 9.2 KiB

130
web_tree_dynamic_colored_field/static/src/js/web_tree_dynamic_colored_field.js

@ -0,0 +1,130 @@
odoo.define('web_tree_dynamic_colored_field', function (require) {
'use strict';
var ListRenderer = require('web.ListRenderer');
var pyUtils = require("web.py_utils");
ListRenderer.include({
/**
* Look up for a `color_field` parameter in tree `colors` attribute
*
* @override
*/
_renderBody: function () {
if (this.arch.attrs.colors) {
var colorAttr = this.arch.attrs.colors.split(';');
if (colorAttr.length > 0) {
var colorField = colorAttr[0].split(':')[1].trim();
// validate the presence of that field in tree view
if (this.state.data.length && colorField in this.state.data[0].data) {
this.colorField = colorField;
} else {
console.warn(
"No field named '" + colorField + "' present in view."
);
}
}
}
return this._super();
},
/**
* Colorize a cell during it's render
*
* @override
*/
_renderBodyCell: function (record, node, colIndex, options) {
var $td = this._super.apply(this, arguments);
var ctx = this.getEvalContext(record);
this.applyColorize($td, record, node, ctx);
return $td;
},
/**
* Colorize the current cell depending on expressions provided.
*
* @param {Query Node} $td a <td> tag inside a table representing a list view
* @param {Object} node an XML node (must be a <field>)
*/
applyColorize: function ($td, record, node, ctx) {
// safely resolve value of `color_field` given in <tree>
var treeColor = record.data[this.colorField];
if (treeColor) {
$td.css('color', treeColor);
}
// apply <field>'s own `options`
if (!node.attrs.options) { return; }
if (node.tag !== 'field') { return; }
var nodeOptions = node.attrs.options;
if (!_.isObject(nodeOptions)) {
nodeOptions = pyUtils.py_eval(nodeOptions);
}
this.applyColorizeHelper($td, nodeOptions, node, 'fg_color', 'color', ctx);
this.applyColorizeHelper($td, nodeOptions, node, 'bg_color', 'background-color', ctx);
},
/**
* @param {Object} nodeOptions a mapping of nodeOptions parameters to the color itself
* @param {Object} node an XML node (must be a <field>)
* @param {string} nodeAttribute an attribute of a node to apply a style onto
* @param {string} cssAttribute a real CSS-compatible attribute
*/
applyColorizeHelper: function ($td, nodeOptions, node, nodeAttribute, cssAttribute, ctx) {
if (nodeOptions[nodeAttribute]) {
var colors = _(nodeOptions[nodeAttribute].split(';'))
.chain()
.map(this.pairColors)
.value()
.filter(function CheckUndefined(value, index, ar) {
return value !== undefined;
});
for (var i=0, len=colors.length; i<len; ++i) {
var pair = colors[i],
color = pair[0],
expression = pair[1];
if (py.evaluate(expression, ctx).toJSON()) {
$td.css(cssAttribute, color);
}
}
}
},
/**
* Parse `<color>: <field> <operator> <value>` forms to
* evaluable expressions
*
* @param {string} pairColor `color: expression` pair
*/
pairColors: function (pairColor) {
if (pairColor !== "") {
var pairList = pairColor.split(':'),
color = pairList[0],
// if one passes a bare color instead of an expression,
// then we consider that color is to be shown in any case
expression = pairList[1]? pairList[1] : 'True';
return [color, py.parse(py.tokenize(expression)), expression];
}
return undefined;
},
/**
* Construct domain evaluation context, mostly by passing
* record's fields's values to local scope.
*
* @param {Object} record a record to build a context from
*/
getEvalContext: function (record) {
var ctx = _.extend(
{},
record.data,
pyUtils.context()
);
for (var key in ctx) {
var value = ctx[key];
if (ctx[key] instanceof moment) {
// date/datetime fields are represented w/ Moment objects
// docs: https://momentjs.com/
ctx[key] = value.format('YYYY-MM-DD hh:mm:ss');
}
}
return ctx;
}
});
});

8
web_tree_dynamic_colored_field/views/web_tree_dynamic_colored_field.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets_backend" name="web_tree_dynamic_colored_field assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/web_tree_dynamic_colored_field/static/src/js/web_tree_dynamic_colored_field.js"/>
</xpath>
</template>
</odoo>
Loading…
Cancel
Save