[IMP] Web: ListView: semantics classes for row decoration

based on bootstrap contextual colors, and bold/italic fonts.

Backward compatibility is ensured as the ListView is monkey-patched
to keep interpreting colors and fonts attributes.
This commit is contained in:
Aaron Bohy
2015-05-15 09:17:18 +02:00
parent a9522cb46f
commit e7ff2d2c6a
7 changed files with 142 additions and 79 deletions
+6
View File
@@ -2555,6 +2555,12 @@
height: 27px;
border-top: 1px solid #ddd;
}
.openerp .oe_list_content > tbody > tr.text-bf {
font-weight: bold;
}
.openerp .oe_list_content > tbody > tr.text-it {
font-style: italic;
}
.openerp .oe_list_content > tbody > tr > td.oe_list_field_cell {
padding: 3px 6px;
white-space: pre-line;
+4
View File
@@ -2103,6 +2103,10 @@ $sheet-padding: 16px
> tr
height: $row-height
border-top: 1px solid #ddd
&.text-bf
font-weight: bold
&.text-it
font-style: italic
> td.oe_list_field_cell
padding: 3px 6px
white-space: pre-line
+78
View File
@@ -183,6 +183,84 @@ function start_modules (modules) {
return openerp;
};
// Monkey-patching of the ListView for backward compatibiliy of the colors and
// fonts row's attributes, as they are deprecated in 9.0.
ListView.include({
load_list: function(data) {
this._super(data);
if (this.fields_view.arch.attrs.colors) {
this.colors = _(this.fields_view.arch.attrs.colors.split(';')).chain()
.compact()
.map(function(color_pair) {
var pair = color_pair.split(':'),
color = pair[0],
expr = pair[1];
return [color, py.parse(py.tokenize(expr)), expr];
}).value();
}
if (this.fields_view.arch.attrs.fonts) {
this.fonts = _(this.fields_view.arch.attrs.fonts.split(';')).chain().compact()
.map(function(font_pair) {
var pair = font_pair.split(':'),
font = pair[0],
expr = pair[1];
return [font, py.parse(py.tokenize(expr)), expr];
}).value();
}
},
/**
* Returns the style for the provided record in the current view (from the
* ``@colors`` and ``@fonts`` attributes)
*
* @param {Record} record record for the current row
* @returns {String} CSS style declaration
*/
style_for: function (record) {
var len, style= '';
var context = _.extend({}, record.attributes, {
uid: session.uid,
current_date: moment().format('YYYY-MM-DD')
// TODO: time, datetime, relativedelta
});
var i;
var pair;
var expression;
if (this.fonts) {
for(i=0, len=this.fonts.length; i<len; ++i) {
pair = this.fonts[i];
var font = pair[0];
expression = pair[1];
if (py.PY_isTrue(py.evaluate(expression, context))) {
switch(font) {
case 'bold':
style += 'font-weight: bold;';
break;
case 'italic':
style += 'font-style: italic;';
break;
case 'underline':
style += 'text-decoration: underline;';
break;
}
}
}
}
if (!this.colors) { return style; }
for(i=0, len=this.colors.length; i<len; ++i) {
pair = this.colors[i];
var color = pair[0];
expression = pair[1];
if (py.PY_isTrue(py.evaluate(expression, context))) {
return style += 'color: ' + color + ';';
}
}
return style;
},
});
});
+29 -59
View File
@@ -20,6 +20,18 @@ var _lt = core._lt;
var QWeb = core.qweb;
var list_widget_registry = core.list_widget_registry;
// Allowed decoration on the list's rows: bold, italic and bootstrap semantics classes
var row_decoration = [
'decoration-bf',
'decoration-it',
'decoration-danger',
'decoration-info',
'decoration-muted',
'decoration-primary',
'decoration-success',
'decoration-warning'
];
var ListView = View.extend( /** @lends instance.web.ListView# */ {
_template: 'ListView',
display_name: _lt('List'),
@@ -166,55 +178,26 @@ var ListView = View.extend( /** @lends instance.web.ListView# */ {
return this._super();
},
/**
* Returns the style for the provided record in the current view (from the
* ``@colors`` and ``@fonts`` attributes)
* Computes and returns the classnames for the provided record (from the
* ``@decoration`` attribute)
*
* @param {Record} record record for the current row
* @returns {String} CSS style declaration
* @returns {String} classnames
*/
style_for: function (record) {
var len, style= '';
compute_decoration_classnames: function (record) {
var classnames= '';
var context = _.extend({}, record.attributes, {
uid: session.uid,
current_date: moment().format('YYYY-MM-DD')
// TODO: time, datetime, relativedelta
});
var i;
var pair;
var expression;
if (this.fonts) {
for(i=0, len=this.fonts.length; i<len; ++i) {
pair = this.fonts[i];
var font = pair[0];
expression = pair[1];
if (py.PY_isTrue(py.evaluate(expression, context))) {
switch(font) {
case 'bold':
style += 'font-weight: bold;';
break;
case 'italic':
style += 'font-style: italic;';
break;
case 'underline':
style += 'text-decoration: underline;';
break;
}
}
}
}
if (!this.colors) { return style; }
for(i=0, len=this.colors.length; i<len; ++i) {
pair = this.colors[i];
var color = pair[0];
expression = pair[1];
if (py.PY_isTrue(py.evaluate(expression, context))) {
return style += 'color: ' + color + ';';
_.each(this.decoration, function(expr, decoration) {
if (py.PY_isTrue(py.evaluate(expr, context))) {
classnames += ' ' + decoration.replace('decoration', 'text');
}
// TODO: handle evaluation errors
}
return style;
});
return classnames;
},
/**
* Called after loading the list view's description, sets up such things
@@ -243,26 +226,13 @@ var ListView = View.extend( /** @lends instance.web.ListView# */ {
this.fields_view = data;
this.name = "" + this.fields_view.arch.attrs.string;
if (this.fields_view.arch.attrs.colors) {
this.colors = _(this.fields_view.arch.attrs.colors.split(';')).chain()
.compact()
.map(function(color_pair) {
var pair = color_pair.split(':'),
color = pair[0],
expr = pair[1];
return [color, py.parse(py.tokenize(expr)), expr];
}).value();
}
if (this.fields_view.arch.attrs.fonts) {
this.fonts = _(this.fields_view.arch.attrs.fonts.split(';')).chain().compact()
.map(function(font_pair) {
var pair = font_pair.split(':'),
font = pair[0],
expr = pair[1];
return [font, py.parse(py.tokenize(expr)), expr];
}).value();
}
// Retrieve the decoration defined on the model's list view
this.decoration = _.pick(this.fields_view.arch.attrs, function(value, key) {
return row_decoration.indexOf(key) >= 0;
});
this.decoration = _.mapObject(this.decoration, function(value) {
return py.parse(py.tokenize(value));
});
this.setup_columns(this.fields_view.fields, this.grouped);
+2 -1
View File
@@ -729,7 +729,8 @@
</t>
<tr t-name="ListView.row"
t-att-data-id="record.get('id')"
t-att-style="view.style_for(record)">
t-attf-style="#{(view.fonts || view.colors) ? view.style_for(record) : ''}"
t-attf-class="#{view.compute_decoration_classnames(record)}">
<t t-set="asData" t-value="record.toForm().data"/>
<t t-foreach="columns" t-as="column">
<td t-if="column.meta"> </td>
+15 -19
View File
@@ -141,28 +141,24 @@ root can have the following attributes:
<tree default_order="sequence,name desc">
``colors``
allows changing the color of a row's text based on the corresponding
.. deprecated:: 9.0
replaced by ``decoration-{$name}``
``fonts``
.. deprecated:: 9.0
replaced by ``decoration-{$name}``
``decoration-{$name}``
allow changing the style of a row's text based on the corresponding
record's attributes.
Defined as a mapping of colors to Python expressions. Values are of the
form: :samp:`{color}:{expr}[;...]`. For each record, pairs are tested
in-order, the expression is evaluated for the record and if ``true`` the
corresponding color is applied to the row. If no color matches, uses the
default text color (black).
Values are Python expressions. For each record, the expression is evaluated
with the record's attributes as context values and if ``true``, the
corresponding style is applied to the row. Other context values are
``uid`` (the id of the current user) and ``current_date`` (the current date
as a string of the form ``yyyy-MM-dd``).
* ``color`` can be any valid `CSS color unit`_.
* ``expr`` should be a Python expression evaluated with the current
record's attributes as context values. Other context values are ``uid``
(the id of the current user) and ``current_date`` (the current date as
a string of the form ``yyyy-MM-dd``)
``fonts``
allows changing a row's font style based on the corresponding record's
attributes.
The format is the same as for ``color``, but the ``color`` of each pair
is replaced by ``bold``, ``italic`` or ``underline``, the expression
evaluating to ``true`` will apply the corresponding style to the row's
text. Contrary to ``colors``, multiple pairs can match each record
``{$name}`` can be ``bf`` (``font-weight: bold``), ``it``
(``font-style: italic``), or any bootstrap contextual color (``danger``,
``info``, ``muted``, ``primary``, ``success`` or ``warning``).
``create``, ``edit``, ``delete``
allows *dis*\ abling the corresponding action in the view by setting the
corresponding attribute to ``false``
+8
View File
@@ -251,6 +251,14 @@
<rng:optional><rng:attribute name="string"/></rng:optional>
<rng:optional><rng:attribute name="colors"/></rng:optional>
<rng:optional><rng:attribute name="fonts"/></rng:optional>
<rng:optional><rng:attribute name="decoration-bf"/></rng:optional>
<rng:optional><rng:attribute name="decoration-it"/></rng:optional>
<rng:optional><rng:attribute name="decoration-danger"/></rng:optional>
<rng:optional><rng:attribute name="decoration-info"/></rng:optional>
<rng:optional><rng:attribute name="decoration-muted"/></rng:optional>
<rng:optional><rng:attribute name="decoration-primary"/></rng:optional>
<rng:optional><rng:attribute name="decoration-success"/></rng:optional>
<rng:optional><rng:attribute name="decoration-warning"/></rng:optional>
<rng:optional>
<rng:attribute name="editable">
<rng:choice>