summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/views/basic
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2017-07-28 18:37:10 +0200
committerChristophe Simonis <chs@odoo.com>2017-07-28 18:37:10 +0200
commit4d5ff6401cabd5a1c86cb15ec9189c8c29620439 (patch)
tree3cc3f5265c022c34bbc1e4f30091e9e389f56427 /addons/web/static/src/js/views/basic
parent7de78e773783b9e24cb2031591887697f2038587 (diff)
parentb76109173a8ddb2fbfe9cca29b759ec86fdc0f75 (diff)
[MERGE] forward port branch saas-16 up to b76109173a8
Diffstat (limited to 'addons/web/static/src/js/views/basic')
-rw-r--r--addons/web/static/src/js/views/basic/basic_controller.js11
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js38
-rw-r--r--addons/web/static/src/js/views/basic/basic_renderer.js24
3 files changed, 47 insertions, 26 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_controller.js b/addons/web/static/src/js/views/basic/basic_controller.js
index cc72816a85d..54c8ccfbf51 100644
--- a/addons/web/static/src/js/views/basic/basic_controller.js
+++ b/addons/web/static/src/js/views/basic/basic_controller.js
@@ -362,17 +362,6 @@ var BasicController = AbstractController.extend(FieldManagerMixin, {
};
},
/**
- * Used by list and kanban views to determine whether or not to display
- * the no content helper (if there is no data in the state to display)
- *
- * @private
- * @param {Object} state
- * @returns {boolean}
- */
- _hasContent: function (state) {
- return state.count !== 0;
- },
- /**
* Helper function to display a warning that some fields have an invalid
* value. This is used when a save operation cannot be completed.
*
diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js
index 8f679207f00..04fe384afdc 100644
--- a/addons/web/static/src/js/views/basic/basic_model.js
+++ b/addons/web/static/src/js/views/basic/basic_model.js
@@ -628,12 +628,12 @@ var BasicModel = AbstractModel.extend({
*
* @param {string} record_id
* @param {Object} changes a map field => new value
- * @param {string} [viewType] current viewType. If not set, we will assume
- * main viewType from the record
+ * @param {Object} [options] will be transferred to the applyChange method
+ * @see _applyChange
* @returns {string[]} list of changed fields
*/
- notifyChanges: function (record_id, changes, viewType) {
- return this.mutex.exec(this._applyChange.bind(this, record_id, changes, viewType));
+ notifyChanges: function (record_id, changes, options) {
+ return this.mutex.exec(this._applyChange.bind(this, record_id, changes, options));
},
/**
* Reload all data for a given resource
@@ -956,23 +956,30 @@ var BasicModel = AbstractModel.extend({
*
* @param {string} recordID
* @param {Object} changes
- * @param {string} [viewType] current viewType. If not set, we will assume
+ * @param {Object} [options]
+ * @param {boolean} [options.doNotSetDirty=false] if this flag is set to
+ * true, then we will not tag the record as dirty. This should be avoided
+ * for most situations.
+ * @param {string} [options.viewType] current viewType. If not set, we will assume
* main viewType from the record
* @returns {Deferred}
*/
- _applyChange: function (recordID, changes, viewType) {
+ _applyChange: function (recordID, changes, options) {
var self = this;
var record = this.localData[recordID];
var field;
var defs = [];
+ options = options || {};
record._changes = record._changes || {};
- record._isDirty = true;
+ if (!options.doNotSetDirty) {
+ record._isDirty = true;
+ }
// apply changes to local data
for (var fieldName in changes) {
field = record.fields[fieldName];
if (field.type === 'one2many' || field.type === 'many2many') {
- defs.push(this._applyX2ManyChange(record, fieldName, changes[fieldName], viewType));
+ defs.push(this._applyX2ManyChange(record, fieldName, changes[fieldName], options.viewType));
} else if (field.type === 'many2one' || field.type === 'reference') {
defs.push(this._applyX2OneChange(record, fieldName, changes[fieldName]));
} else {
@@ -993,7 +1000,7 @@ var BasicModel = AbstractModel.extend({
}
var onchangeDef;
if (onChangeFields.length) {
- onchangeDef = self._performOnChange(record, onChangeFields, viewType).then(function (result) {
+ onchangeDef = self._performOnChange(record, onChangeFields, options.viewType).then(function (result) {
delete record._warning;
return _.keys(changes).concat(Object.keys(result && result.value || {}));
});
@@ -2196,7 +2203,7 @@ var BasicModel = AbstractModel.extend({
// remove readonly fields from the list of changes
if (!withReadonly && fieldName in changes || fieldName in commands) {
var editionViewType = record._editionViewType[fieldName] || viewType;
- if (this._isFieldReadonly(record, fieldName, editionViewType)) {
+ if (this._isFieldProtected(record, fieldName, editionViewType)) {
delete changes[fieldName];
continue;
}
@@ -2555,9 +2562,10 @@ var BasicModel = AbstractModel.extend({
return context;
},
/**
- * Returns true if the field is readonly (checking first in the modifiers,
- * and if there is no readonly modifier, checking the readonly attribute of
- * the field).
+ * Returns true if the field is protected against changes, looking for a
+ * readonly modifier unless there is a force_save modifier (checking first
+ * in the modifiers, and if there is no readonly modifier, checking the
+ * readonly attribute of the field).
*
* @private
* @param {Object} record an element from the localData
@@ -2566,12 +2574,12 @@ var BasicModel = AbstractModel.extend({
* main viewType from the record
* @returns {boolean}
*/
- _isFieldReadonly: function (record, fieldName, viewType) {
+ _isFieldProtected: function (record, fieldName, viewType) {
var fieldInfo = record.fieldsInfo[viewType || record.viewType][fieldName];
if (fieldInfo) {
var rawModifiers = JSON.parse(fieldInfo.modifiers || "{}");
var modifiers = this._evalModifiers(record, rawModifiers);
- return modifiers.readonly;
+ return modifiers.readonly && !fieldInfo.force_save;
} else {
return false;
}
diff --git a/addons/web/static/src/js/views/basic/basic_renderer.js b/addons/web/static/src/js/views/basic/basic_renderer.js
index 8bbf9ae45a4..e040a5fa7f0 100644
--- a/addons/web/static/src/js/views/basic/basic_renderer.js
+++ b/addons/web/static/src/js/views/basic/basic_renderer.js
@@ -318,6 +318,16 @@ var BasicRenderer = AbstractRenderer.extend({
return _.findWhere(this.allModifiersData, {node: node});
},
/**
+ * Used by list and kanban renderers to determine whether or not to display
+ * the no content helper (if there is no data in the state to display)
+ *
+ * @private
+ * @returns {boolean}
+ */
+ _hasContent: function () {
+ return this.state.count !== 0;
+ },
+ /**
* Registers or updates the modifiers data associated to the given node.
* This method is quiet complex as it handles all the needs of the basic
* renderers:
@@ -487,6 +497,20 @@ var BasicRenderer = AbstractRenderer.extend({
return widget;
},
/**
+ * Renders the nocontent helper.
+ *
+ * This method is a helper for renderers that want to display a help
+ * message when no content is available.
+ *
+ * @private
+ */
+ _renderNoContentHelper: function () {
+ var $msg = $('<div>')
+ .addClass('oe_view_nocontent')
+ .html(this.noContentHelp);
+ this.$el.html($msg);
+ },
+ /**
* Actual rendering. Supposed to be overridden by concrete renderers.
* The basic responsabilities of _renderView are:
* - use the xml arch of the view to render a jQuery representation