diff --git a/web_tree_dynamic_colored_field/README.rst b/web_tree_dynamic_colored_field/README.rst index ccc59f9b..d661197c 100644 --- a/web_tree_dynamic_colored_field/README.rst +++ b/web_tree_dynamic_colored_field/README.rst @@ -1,35 +1,37 @@ +.. image:: https://img.shields.io/badge/license-LGPL--3-blue.svg + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-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 same syntax as the 'colors' attribute +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 to use a field's -value as color. +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 fields to color background of a cell in tree view - -* Add attribute ``fg_color`` on fields to change text color of a cell in tree view - -* Add attribute ``color_field`` on the tree element to use as color - +* 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 bg_color="red:customer==True;" attribute in the field tag:: +* In the tree view declaration, put ``options='"bg_color": "red: customer==True"`` attribute in the ``field`` tag:: ... ... - + ... @@ -37,37 +39,39 @@ Usage With this example, column which renders 'name' field will have its background colored in red. -* In the tree view declaration, put fg_color="white:customer==True;" attribute in the field tag:: +* In the tree view declaration, put ``options='"fg_color": "white:customer == True"'`` attribute in the ``field`` tag:: ... ... - + ... ... - With this example, column which renders 'name' field will have its text colored in white. + 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 color_field="color" attribute in the tree tag:: +* In the tree view declaration, use ``options='"color_field": "my_color"'`` attribute in the ``tree`` tag:: ... - + ... - + ... ... - With this example, the content of the field named `color` will be used to - populate the `color` CSS value. Use a function field to return whichever + 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 `colors` attribute, and that you need the tree to load your - field in the first place by adding it as invisible field. + 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 =========== @@ -75,7 +79,7 @@ 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. +help us smash it by providing a detailed and welcomed feedback. Credits ======= @@ -85,6 +89,7 @@ Contributors * Damien Crier * Holger Brunn +* Artem Kostyuk Maintainer ---------- diff --git a/web_tree_dynamic_colored_field/__init__.py b/web_tree_dynamic_colored_field/__init__.py index ed8d9eff..8945c43c 100644 --- a/web_tree_dynamic_colored_field/__init__.py +++ b/web_tree_dynamic_colored_field/__init__.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- -# © 2015 Camptocamp SA, Damien Crier +# Copyright 2015-2018 Camptocamp SA, Damien Crier # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). diff --git a/web_tree_dynamic_colored_field/__manifest__.py b/web_tree_dynamic_colored_field/__manifest__.py index 43e967fb..665310b8 100644 --- a/web_tree_dynamic_colored_field/__manifest__.py +++ b/web_tree_dynamic_colored_field/__manifest__.py @@ -1,13 +1,12 @@ -# -*- coding: utf-8 -*- -# © 2015 Camptocamp SA, Damien Crier +# 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': '10.0.1.0.0', + 'version': '11.0.1.0.0', 'depends': ['web'], - 'author': "Camptocamp,Therp BV,Odoo Community Association (OCA)", + 'author': "Camptocamp, Therp BV, Odoo Community Association (OCA)", 'license': 'AGPL-3', 'website': 'https://github.com/OCA/web', 'demo': [ @@ -16,7 +15,5 @@ 'data': [ 'views/web_tree_dynamic_colored_field.xml', ], - 'qweb': [ - 'static/src/xml/*.xml', - ], + 'installable': True, } diff --git a/web_tree_dynamic_colored_field/demo/res_users.xml b/web_tree_dynamic_colored_field/demo/res_users.xml index 806b8767..ef364722 100644 --- a/web_tree_dynamic_colored_field/demo/res_users.xml +++ b/web_tree_dynamic_colored_field/demo/res_users.xml @@ -4,17 +4,21 @@ res.users - - lang - - - red: login_date == False - white: login_date == False - - - red: login == 'admin' - white: login == 'admin' - + + color_field: lang + + + { + "bg_color": "#9e1635: login_date == False", + "fg_color": "white: login_date == False" + } + + + { + "bg_color": "blue; #653b5b: login == 'admin'", + "fg_color": "white" + } + diff --git a/web_tree_dynamic_colored_field/i18n/es.po b/web_tree_dynamic_colored_field/i18n/es.po deleted file mode 100644 index 6e6aeff9..00000000 --- a/web_tree_dynamic_colored_field/i18n/es.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_tree_dynamic_colored_field -# -# Translators: -# Pedro M. Baeza , 2017 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 9.0c\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-01-05 01:38+0000\n" -"PO-Revision-Date: 2017-01-05 01:38+0000\n" -"Last-Translator: Pedro M. Baeza , 2017\n" -"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: es\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_tree_dynamic_colored_field -#. openerp-web -#: code:addons/web_tree_dynamic_colored_field/static/src/xml/web_tree_dynamic_colored_field.xml:7 -#, python-format -msgid "columns.fct_colorize(record, column)" -msgstr "columns.fct_colorize(record, column)" diff --git a/web_tree_dynamic_colored_field/i18n/fi.po b/web_tree_dynamic_colored_field/i18n/fi.po deleted file mode 100644 index acf992c3..00000000 --- a/web_tree_dynamic_colored_field/i18n/fi.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_tree_dynamic_colored_field -# -# Translators: -# Jarmo Kortetjärvi , 2016 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 8.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-07-08 16:36+0000\n" -"PO-Revision-Date: 2016-07-08 16:36+0000\n" -"Last-Translator: Jarmo Kortetjärvi , 2016\n" -"Language-Team: Finnish (https://www.transifex.com/oca/teams/23907/fi/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: fi\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_tree_dynamic_colored_field -#. openerp-web -#: code:addons/web_tree_dynamic_colored_field/static/src/xml/web_tree_dynamic_colored_field.xml:7 -#, python-format -msgid "columns.fct_colorize(record, column)" -msgstr "columns.fct_colorize(record, column)" diff --git a/web_tree_dynamic_colored_field/i18n/nl_NL.po b/web_tree_dynamic_colored_field/i18n/nl_NL.po deleted file mode 100644 index edc9e2e2..00000000 --- a/web_tree_dynamic_colored_field/i18n/nl_NL.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_tree_dynamic_colored_field -# -# Translators: -# Peter Hageman , 2017 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 10.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-22 08:27+0000\n" -"PO-Revision-Date: 2017-06-22 08:27+0000\n" -"Last-Translator: Peter Hageman , 2017\n" -"Language-Team: Dutch (Netherlands) (https://www.transifex.com/oca/teams/23907/nl_NL/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: nl_NL\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: web_tree_dynamic_colored_field -#. openerp-web -#: code:addons/web_tree_dynamic_colored_field/static/src/xml/web_tree_dynamic_colored_field.xml:7 -#, python-format -msgid "columns.fct_colorize(record, column)" -msgstr "columns.fct_colorize(record, column)" diff --git a/web_tree_dynamic_colored_field/i18n/sl.po b/web_tree_dynamic_colored_field/i18n/sl.po deleted file mode 100644 index c37ce8ab..00000000 --- a/web_tree_dynamic_colored_field/i18n/sl.po +++ /dev/null @@ -1,26 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * web_tree_dynamic_colored_field -# -# Translators: -# Matjaž Mozetič , 2016 -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 8.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-06-24 00:46+0000\n" -"PO-Revision-Date: 2016-06-24 00:46+0000\n" -"Last-Translator: Matjaž Mozetič , 2016\n" -"Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: sl\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_tree_dynamic_colored_field -#. openerp-web -#: code:addons/web_tree_dynamic_colored_field/static/src/xml/web_tree_dynamic_colored_field.xml:7 -#, python-format -msgid "columns.fct_colorize(record, column)" -msgstr "columns.fct_colorize(record, column)" diff --git a/web_tree_dynamic_colored_field/static/src/js/web_tree_dynamic_colored_field.js b/web_tree_dynamic_colored_field/static/src/js/web_tree_dynamic_colored_field.js index 1d3a9273..2a96aba6 100644 --- a/web_tree_dynamic_colored_field/static/src/js/web_tree_dynamic_colored_field.js +++ b/web_tree_dynamic_colored_field/static/src/js/web_tree_dynamic_colored_field.js @@ -1,95 +1,129 @@ -odoo.define('web_tree_dynamic_colored_field', function(require) -{ +odoo.define('web_tree_dynamic_colored_field', function (require) { 'use strict'; - var ListView = require('web.ListView'), - pyeval = require('web.pyeval'), - py = window.py; - var pair_colors = function(pair_color){ - if (pair_color !== ""){ - var pair_list = pair_color.split(':'), - color = pair_list[0], - expression = pair_list[1]; - return [color, py.parse(py.tokenize(expression)), expression]; - } - }; - - var get_eval_context = function(record){ - return _.extend( - {}, - record.attributes, - pyeval.context() - ); - }; + var ListRenderer = require('web.ListRenderer'); + var pyeval = require('web.pyeval'); - var colorize_helper = function(obj, record, column, field_attribute, css_attribute){ - var result = ''; - if (column[field_attribute]){ - var colors = _(column[field_attribute].split(';')) - .chain() - .map(pair_colors) - .value() - .filter(function CheckUndefined(value, index, ar) { - return value !== undefined; - }); - var ctx = get_eval_context(record); - for(var i=0, len=colors.length; i color.trim().startsWith('color_field'))[0] + .split(':')[1] + .trim(); + // validate the presence of that field in tree view + var fieldNames = _(this.columns).map( + (value) => { return value.attrs.name; } + ); + if (fieldNames.indexOf(colorField) === -1) { + console.warn( + "No field named '" + colorField + "' present in view." + ); + } else { + this.colorField = colorField; } } - } - return result; - }; - - var colorize = function(record, column){ - var res = ''; - res += colorize_helper(this, record, column, 'bg_color', 'background-color'); - res += colorize_helper(this, record, column, 'fg_color', 'color'); - return res; - }; - - ListView.List.include({ - init: function(group, opts){ - this._super(group, opts); - this.columns.fct_colorize = colorize; + 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; }, - }); - ListView.include({ - load_view: function() - { - var self = this; - return this._super.apply(this, arguments) - .then(function() - { - // the style_for helper is only called if one of colors or - // fonts is not null - if(self.fields_view.arch.attrs.color_field) - { - self.colors = []; - } - }); + /** + * Colorize the current cell depending on expressions provided. + * + * @param {Query Node} $td a tag inside a table representing a list view + * @param {Object} node an XML node (must be a ) + */ + applyColorize: function ($td, record, node, ctx) { + // safely resolve value of `color_field` given in + var treeColor = record.data[this.colorField]; + if (treeColor) { + $td.css('color', treeColor); + } + // apply 's own `options` + if (!node.attrs.options) { return; } + var nodeOptions = JSON.parse(node.attrs.options); + this.applyColorizeHelper($td, nodeOptions, node, 'fg_color', 'color', ctx); + this.applyColorizeHelper($td, nodeOptions, node, 'bg_color', 'background-color', ctx); }, - style_for: function (record) - { - var result = this._super.apply(this, arguments); - if(this.fields_view.arch.attrs.color_field) - { - var color = py.evaluate( - py.parse(py.tokenize( - this.fields_view.arch.attrs.color_field - )), - get_eval_context(record)).toJSON(); - if(color) - { - result += 'color: ' + color; + /** + * @param {Object} nodeOptions a mapping of nodeOptions parameters to the color itself + * @param {Object} node an XML node (must be a ) + * @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: ` forms to + * evaluatable 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, + pyeval.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; + } }); }); diff --git a/web_tree_dynamic_colored_field/static/src/xml/web_tree_dynamic_colored_field.xml b/web_tree_dynamic_colored_field/static/src/xml/web_tree_dynamic_colored_field.xml deleted file mode 100644 index 254172e8..00000000 --- a/web_tree_dynamic_colored_field/static/src/xml/web_tree_dynamic_colored_field.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - columns.fct_colorize(record, column) - - - - diff --git a/web_tree_dynamic_colored_field/views/web_tree_dynamic_colored_field.xml b/web_tree_dynamic_colored_field/views/web_tree_dynamic_colored_field.xml index c634300c..ea8e1129 100644 --- a/web_tree_dynamic_colored_field/views/web_tree_dynamic_colored_field.xml +++ b/web_tree_dynamic_colored_field/views/web_tree_dynamic_colored_field.xml @@ -1,6 +1,4 @@ -