Skip to content
Snippets Groups Projects
Commit 56787d58 authored by Aaron Bohy's avatar Aaron Bohy
Browse files

[REF] web: field decoration

This commit refactors the way the decoration-xxx attributes are
applied to field widgets/components, in a way that it can be
overridden in a given field or component to generate the approriate
className. By default, 'decoration-x' applies className 'text-x'.

This will be necessary for the new 'FieldBadge' component, which
needs to apply 'bg-x' classNames instead of 'text-x'.

Part of task 2195254
parent a1d3e224
No related branches found
No related tags found
No related merge requests found
...@@ -370,7 +370,8 @@ var AbstractField = Widget.extend({ ...@@ -370,7 +370,8 @@ var AbstractField = Widget.extend({
var isToggled = py.PY_isTrue( var isToggled = py.PY_isTrue(
py.evaluate(dec.expression, self.record.evalContext) py.evaluate(dec.expression, self.record.evalContext)
); );
self.$el.toggleClass(dec.className, isToggled); const className = self._getClassFromDecoration(dec.name);
self.$el.toggleClass(className, isToggled);
}); });
}, },
/** /**
...@@ -384,6 +385,18 @@ var AbstractField = Widget.extend({ ...@@ -384,6 +385,18 @@ var AbstractField = Widget.extend({
var options = _.extend({}, this.nodeOptions, { data: this.recordData }, this.formatOptions); var options = _.extend({}, this.nodeOptions, { data: this.recordData }, this.formatOptions);
return field_utils.format[this.formatType](value, this.field, options); return field_utils.format[this.formatType](value, this.field, options);
}, },
/**
* Returns the className corresponding to a given decoration. A
* decoration is of the form 'decoration-%s'. By default, replaces
* 'decoration' by 'text'.
*
* @private
* @param {string} decoration must be of the form 'decoration-%s'
* @returns {string}
*/
_getClassFromDecoration: function (decoration) {
return `text-${decoration.split('-')[1]}`;
},
/** /**
* This method check if a value is the same as the current value of the * This method check if a value is the same as the current value of the
* field. For example, a fieldDate widget might want to use the moment * field. For example, a fieldDate widget might want to use the moment
......
...@@ -9,13 +9,13 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -9,13 +9,13 @@ odoo.define('web.AbstractFieldOwl', function (require) {
/** /**
* This file defines the Owl version of the AbstractField. Specific fields * This file defines the Owl version of the AbstractField. Specific fields
* written in Owl should override this component. * written in Owl should override this component.
* *
* ========================================================================= * =========================================================================
* *
* /!\ This api works almost exactly like the legacy one but * /!\ This api works almost exactly like the legacy one but
* /!\ it still could change! There are already a few methods that will be * /!\ it still could change! There are already a few methods that will be
* /!\ removed like setIdForLabel, setInvalidClass, etc.. * /!\ removed like setIdForLabel, setInvalidClass, etc..
* *
* ========================================================================= * =========================================================================
* *
* This is the basic field component used by all the views to render a field in a view. * This is the basic field component used by all the views to render a field in a view.
...@@ -105,7 +105,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -105,7 +105,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
/** /**
* This contains the attributes to pass through the context. * This contains the attributes to pass through the context.
* *
* @returns {Object} * @returns {Object}
*/ */
get additionalContext() { get additionalContext() {
...@@ -113,7 +113,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -113,7 +113,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
} }
/** /**
* This contains the attributes of the xml 'field' tag, the inner views... * This contains the attributes of the xml 'field' tag, the inner views...
* *
* @returns {Object} * @returns {Object}
*/ */
get attrs() { get attrs() {
...@@ -124,7 +124,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -124,7 +124,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
* Id corresponding to the current record in the model. * Id corresponding to the current record in the model.
* Its intended use is to be able to tag any messages going upstream, * Its intended use is to be able to tag any messages going upstream,
* so the view knows which records was changed for example. * so the view knows which records was changed for example.
* *
* @returns {string} * @returns {string}
*/ */
get dataPointId() { get dataPointId() {
...@@ -133,7 +133,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -133,7 +133,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
/** /**
* This is a description of all the various field properties, * This is a description of all the various field properties,
* such as the type, the comodel (relation), ... * such as the type, the comodel (relation), ...
* *
* @returns {string} * @returns {string}
*/ */
get field() { get field() {
...@@ -150,7 +150,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -150,7 +150,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
/** /**
* Returns the additional options pass to the format function. * Returns the additional options pass to the format function.
* Override this getter to add options. * Override this getter to add options.
* *
* @returns {Object} * @returns {Object}
*/ */
get formatOptions() { get formatOptions() {
...@@ -164,7 +164,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -164,7 +164,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
* the 'widget' attrs if is is given, and if it is a valid key, with a * the 'widget' attrs if is is given, and if it is a valid key, with a
* fallback on the field type, ensuring that the value is formatted and * fallback on the field type, ensuring that the value is formatted and
* displayed according to the chosen widget, if any. * displayed according to the chosen widget, if any.
* *
* @returns {string} * @returns {string}
*/ */
get formatType() { get formatType() {
...@@ -205,7 +205,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -205,7 +205,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
* Tracks if the component is in a valid state, meaning that the current * Tracks if the component is in a valid state, meaning that the current
* value represented in the DOM is a value that can be parsed and saved. * value represented in the DOM is a value that can be parsed and saved.
* For example, a float field can only use a number and not a string. * For example, a float field can only use a number and not a string.
* *
* @returns {boolean} * @returns {boolean}
*/ */
get isValid() { get isValid() {
...@@ -213,7 +213,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -213,7 +213,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
} }
/** /**
* Fields can be in two modes: 'edit' or 'readonly'. * Fields can be in two modes: 'edit' or 'readonly'.
* *
* @returns {string} * @returns {string}
*/ */
get mode() { get mode() {
...@@ -221,7 +221,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -221,7 +221,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
} }
/** /**
* Useful mostly to trigger rpcs on the correct model. * Useful mostly to trigger rpcs on the correct model.
* *
* @returns {string} * @returns {string}
*/ */
get model() { get model() {
...@@ -229,7 +229,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -229,7 +229,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
} }
/** /**
* The field name displayed by this component. * The field name displayed by this component.
* *
* @returns {string} * @returns {string}
*/ */
get name() { get name() {
...@@ -238,7 +238,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -238,7 +238,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
/** /**
* Component can often be configured in the 'options' attribute in the * Component can often be configured in the 'options' attribute in the
* xml 'field' tag. These options are saved (and evaled) in nodeOptions. * xml 'field' tag. These options are saved (and evaled) in nodeOptions.
* *
* @returns {Object} * @returns {Object}
*/ */
get nodeOptions() { get nodeOptions() {
...@@ -253,7 +253,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -253,7 +253,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
/** /**
* Returns the additional options passed to the parse function. * Returns the additional options passed to the parse function.
* Override this getter to add options. * Override this getter to add options.
* *
* @returns {Object} * @returns {Object}
*/ */
get parseOptions() { get parseOptions() {
...@@ -261,7 +261,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -261,7 +261,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
} }
/** /**
* The datapoint fetched from the model. * The datapoint fetched from the model.
* *
* @returns {Object} * @returns {Object}
*/ */
get record() { get record() {
...@@ -273,7 +273,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -273,7 +273,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
* use this to try to change other fields value, this is not how it is * use this to try to change other fields value, this is not how it is
* supposed to work. Also, do not use this.recordData[this.name] to get * supposed to work. Also, do not use this.recordData[this.name] to get
* the current value, this could be out of sync after a _setValue. * the current value, this could be out of sync after a _setValue.
* *
* @returns {Object} * @returns {Object}
*/ */
get recordData() { get recordData() {
...@@ -283,10 +283,10 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -283,10 +283,10 @@ odoo.define('web.AbstractFieldOwl', function (require) {
* If this flag is set to true, the field component will be reset on * If this flag is set to true, the field component will be reset on
* every change which is made in the view (if the view supports it). * every change which is made in the view (if the view supports it).
* This is currently a form view feature. * This is currently a form view feature.
* *
* /!\ This getter could be removed when basic views (form, list, kanban) * /!\ This getter could be removed when basic views (form, list, kanban)
* are converted. * are converted.
* *
* @returns {boolean} * @returns {boolean}
*/ */
get resetOnAnyFieldChange() { get resetOnAnyFieldChange() {
...@@ -298,7 +298,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -298,7 +298,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
* When the record will be created, the field component will * When the record will be created, the field component will
* be destroyed (when the form view switches to readonly mode) and a * be destroyed (when the form view switches to readonly mode) and a
* new component with a res_id in mode readonly will be created. * new component with a res_id in mode readonly will be created.
* *
* @returns {Number} * @returns {Number}
*/ */
get resId() { get resId() {
...@@ -308,7 +308,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -308,7 +308,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
* Human readable (and translated) description of the field. * Human readable (and translated) description of the field.
* Mostly useful to be displayed in various places in the * Mostly useful to be displayed in various places in the
* UI, such as tooltips or create dialogs. * UI, such as tooltips or create dialogs.
* *
* @returns {string} * @returns {string}
*/ */
get string() { get string() {
...@@ -316,7 +316,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -316,7 +316,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
} }
/** /**
* Tracks the current (parsed if needed) value of the field. * Tracks the current (parsed if needed) value of the field.
* *
* @returns {any} * @returns {any}
*/ */
get value() { get value() {
...@@ -325,7 +325,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -325,7 +325,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
/** /**
* The type of the view in which the field component is instantiated. * The type of the view in which the field component is instantiated.
* For standalone components, a 'default' viewType is set. * For standalone components, a 'default' viewType is set.
* *
* @returns {string} * @returns {string}
*/ */
get viewType() { get viewType() {
...@@ -378,7 +378,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -378,7 +378,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
commitChanges() {} commitChanges() {}
/** /**
* Remove the invalid class on a field * Remove the invalid class on a field
* *
* This function should be removed when BasicRenderer will be rewritten in owl * This function should be removed when BasicRenderer will be rewritten in owl
*/ */
removeInvalidClass() { removeInvalidClass() {
...@@ -388,7 +388,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -388,7 +388,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
/** /**
* Sets the given id on the focusable element of the field and as 'for' * Sets the given id on the focusable element of the field and as 'for'
* attribute of potential internal labels. * attribute of potential internal labels.
* *
* This function should be removed when BasicRenderer will be rewritten in owl * This function should be removed when BasicRenderer will be rewritten in owl
* *
* @param {string} id * @param {string} id
...@@ -400,7 +400,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -400,7 +400,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
} }
/** /**
* add the invalid class on a field * add the invalid class on a field
* *
* This function should be removed when BasicRenderer will be rewritten in owl * This function should be removed when BasicRenderer will be rewritten in owl
*/ */
setInvalidClass() { setInvalidClass() {
...@@ -417,7 +417,7 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -417,7 +417,7 @@ odoo.define('web.AbstractFieldOwl', function (require) {
* defined in an attribute). * defined in an attribute).
* *
* This function should be removed when BasicRenderer will be rewritten in owl * This function should be removed when BasicRenderer will be rewritten in owl
* *
* @private * @private
*/ */
_applyDecorations() { _applyDecorations() {
...@@ -425,7 +425,8 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -425,7 +425,8 @@ odoo.define('web.AbstractFieldOwl', function (require) {
const isToggled = py.PY_isTrue( const isToggled = py.PY_isTrue(
py.evaluate(dec.expression, this.record.evalContext) py.evaluate(dec.expression, this.record.evalContext)
); );
this.el.classList.toggle(dec.className, isToggled); const className = this._getClassFromDecoration(dec.name);
this.el.classList.toggle(className, isToggled);
} }
} }
/** /**
...@@ -440,6 +441,18 @@ odoo.define('web.AbstractFieldOwl', function (require) { ...@@ -440,6 +441,18 @@ odoo.define('web.AbstractFieldOwl', function (require) {
{ data: this.recordData }, this.formatOptions); { data: this.recordData }, this.formatOptions);
return field_utils.format[this.formatType](value, this.field, options); return field_utils.format[this.formatType](value, this.field, options);
} }
/**
* Returns the className corresponding to a given decoration. A
* decoration is of the form 'decoration-%s'. By default, replaces
* 'decoration' by 'text'.
*
* @private
* @param {string} decoration must be of the form 'decoration-%s'
* @returns {string}
*/
_getClassFromDecoration(decoration) {
return `text-${decoration.split('-')[1]}`;
}
/** /**
* This method check if a value is the same as the current value of the * This method check if a value is the same as the current value of the
* field. For example, a fieldDate component might want to use the moment * field. For example, a fieldDate component might want to use the moment
......
...@@ -232,11 +232,10 @@ var BasicView = AbstractView.extend({ ...@@ -232,11 +232,10 @@ var BasicView = AbstractView.extend({
// process decoration attributes // process decoration attributes
_.each(attrs, function (value, key) { _.each(attrs, function (value, key) {
var splitKey = key.split('-'); if (key.startsWith('decoration-')) {
if (splitKey[0] === 'decoration') {
attrs.decorations = attrs.decorations || []; attrs.decorations = attrs.decorations || [];
attrs.decorations.push({ attrs.decorations.push({
className: 'text-' + splitKey[1], name: key,
expression: pyUtils._getPyJSAST(value), expression: pyUtils._getPyJSAST(value),
}); });
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment