summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2018-05-09 15:45:20 +0200
committerChristophe Simonis <chs@odoo.com>2018-05-09 15:45:20 +0200
commit5a751fa20091fc38b6d9032c1d8504adc3f0a394 (patch)
treeefc44792d39d7e1c1f74d15ae740718d22a62e21 /addons/web/static/src
parentcca15358b655a93205e07ca66025643dd57269ab (diff)
parentaae54ecc159d109a044fbaa8151f1104897f2203 (diff)
[MERGE] forward port branch saas-11.2 up to aae54ecc159
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/js/core/ajax.js8
-rw-r--r--addons/web/static/src/js/fields/relational_fields.js9
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js47
-rw-r--r--addons/web/static/src/js/views/calendar/calendar_view.js16
-rw-r--r--addons/web/static/src/js/views/form/form_controller.js10
-rw-r--r--addons/web/static/src/js/views/form/form_view.js8
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_model.js9
-rw-r--r--addons/web/static/src/js/views/list/list_editable_renderer.js7
-rw-r--r--addons/web/static/src/js/views/pivot/pivot_model.js6
-rw-r--r--addons/web/static/src/less/list_view.less8
10 files changed, 98 insertions, 30 deletions
diff --git a/addons/web/static/src/js/core/ajax.js b/addons/web/static/src/js/core/ajax.js
index 0ee6d2ad1ed..2912b319df2 100644
--- a/addons/web/static/src/js/core/ajax.js
+++ b/addons/web/static/src/js/core/ajax.js
@@ -260,8 +260,12 @@ function get_file(options) {
if (options.error) {
var body = this.contentDocument.body;
var nodes = body.children.length === 0 ? body.childNodes : body.children;
- var node = nodes[1] || nodes[0];
- options.error(JSON.parse(node.textContent));
+ options.error({
+ message: nodes.length > 1 ? nodes[1].textContent : '',
+ data: {
+ title: nodes.length > 0 ? nodes[0].textContent : '',
+ },
+ });
}
} finally {
complete();
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js
index 423dbf40235..21a19e96263 100644
--- a/addons/web/static/src/js/fields/relational_fields.js
+++ b/addons/web/static/src/js/fields/relational_fields.js
@@ -340,8 +340,8 @@ var FieldMany2One = AbstractField.extend({
_renderReadonly: function () {
var value = _.escape((this.m2o_value || "").trim()).split("\n").join("<br/>");
this.$el.html(value);
- if (!this.nodeOptions.no_open) {
- this.$el.attr('href', '#');
+ if (!this.nodeOptions.no_open && this.value) {
+ this.$el.attr('href', _.str.sprintf('#id=%s&model=%s', this.value.res_id, this.field.relation));
this.$el.addClass('o_form_uri');
}
},
@@ -1332,10 +1332,7 @@ var FieldOne2Many = FieldX2Many.extend({
var self = this;
var id = ev.data.id;
- var onSaved = function (record, hasChanged) {
- if (!hasChanged) {
- return;
- }
+ var onSaved = function (record) {
if (_.some(self.value.data, {id: record.id})) {
// the record already exists in the relation, so trigger an
// empty 'UPDATE' operation when the user clicks on 'Save' in
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 75ec31d5deb..d7cc08ea974 100644
--- a/addons/web/static/src/js/views/basic/basic_model.js
+++ b/addons/web/static/src/js/views/basic/basic_model.js
@@ -1068,7 +1068,13 @@ var BasicModel = AbstractModel.extend({
addFieldsInfo: function (recordID, viewInfo) {
var record = this.localData[recordID];
record.fields = _.extend({}, record.fields, viewInfo.fields);
- record.fieldsInfo = _.extend({}, record.fieldsInfo, viewInfo.fieldsInfo);
+ // complete the given fieldsInfo with the fields of the main view, so
+ // that those field will be reloaded if a reload is triggered by the
+ // secondary view
+ var fieldsInfo = _.mapObject(viewInfo.fieldsInfo, function (fieldsInfo) {
+ return _.defaults({}, fieldsInfo, record.fieldsInfo[record.viewType]);
+ });
+ record.fieldsInfo = _.extend({}, record.fieldsInfo, fieldsInfo);
},
/**
* For list resources, this freezes the current records order.
@@ -2010,7 +2016,8 @@ var BasicModel = AbstractModel.extend({
*/
_fetchRecord: function (record, options) {
var self = this;
- var fieldNames = options && options.fieldNames || record.getFieldNames();
+ options = options || {};
+ var fieldNames = options.fieldNames || record.getFieldNames(options);
fieldNames = _.uniq(fieldNames.concat(['display_name']));
return this._rpc({
model: record.model,
@@ -2510,8 +2517,9 @@ var BasicModel = AbstractModel.extend({
_fetchX2Manys: function (record, options) {
var self = this;
var defs = [];
- var fieldNames = options && options.fieldNames || record.getFieldNames();
- var viewType = options && options.viewType || record.viewType;
+ options = options || {};
+ var fieldNames = options.fieldNames || record.getFieldNames(options);
+ var viewType = options.viewType || record.viewType;
_.each(fieldNames, function (fieldName) {
var field = record.fields[fieldName];
if (field.type === 'one2many' || field.type === 'many2many') {
@@ -3034,11 +3042,15 @@ var BasicModel = AbstractModel.extend({
* default view type.
*
* @param {Object} element an element from the localData
+ * @param {Object} [options]
+ * @param {Object} [options.viewType] current viewType. If not set, we will
+ * assume main viewType from the record
* @returns {string[]} the list of field names
*/
- _getFieldNames: function (element) {
+ _getFieldNames: function (element, options) {
var fieldsInfo = element.fieldsInfo;
- return Object.keys(fieldsInfo && fieldsInfo[element.viewType] || {});
+ var viewType = options && options.viewType || element.viewType;
+ return Object.keys(fieldsInfo && fieldsInfo[viewType] || {});
},
/**
* Evaluate the record evaluation context. This method is supposed to be
@@ -3533,13 +3545,16 @@ var BasicModel = AbstractModel.extend({
* @see _fetchRecord @see _makeDefaultRecord
*
* @param {Object} record
- * @param {Object} record
+ * @param {Object} [options]
+ * @param {Object} [options.viewType] current viewType. If not set, we will
+ * assume main viewType from the record
* @returns {Deferred<Object>} resolves to the finished resource
*/
_postprocess: function (record, options) {
var self = this;
var defs = [];
- _.each(record.getFieldNames(), function (name) {
+
+ _.each(record.getFieldNames(options), function (name) {
var field = record.fields[name];
var fieldInfo = record.fieldsInfo[record.viewType][name] || {};
var options = fieldInfo.options || {};
@@ -3879,14 +3894,20 @@ var BasicModel = AbstractModel.extend({
var emptyGroupsIDs = _.difference(_.pluck(previousGroups, 'id'), list.data);
_.each(emptyGroupsIDs, function (groupID) {
list.data.push(groupID);
+ var emptyGroup = self.localData[groupID];
+ // this attribute hasn't been updated in the previous
+ // loop for empty groups
+ emptyGroup.aggregateValues = {};
});
}
return $.when.apply($, defs).then(function () {
- // generate the res_ids of the main list, being the concatenation
- // of the fetched res_ids in each group
- list.res_ids = _.flatten(_.map(arguments, function (group) {
- return group ? group.res_ids : [];
- }));
+ if (!options || !options.onlyGroups) {
+ // generate the res_ids of the main list, being the concatenation
+ // of the fetched res_ids in each group
+ list.res_ids = _.flatten(_.map(arguments, function (group) {
+ return group ? group.res_ids : [];
+ }));
+ }
return list;
});
});
diff --git a/addons/web/static/src/js/views/calendar/calendar_view.js b/addons/web/static/src/js/views/calendar/calendar_view.js
index a813a626565..6c12d508937 100644
--- a/addons/web/static/src/js/views/calendar/calendar_view.js
+++ b/addons/web/static/src/js/views/calendar/calendar_view.js
@@ -118,8 +118,20 @@ var CalendarView = AbstractView.extend({
//if quick_add = is NOT False and IS specified in view, we this one for widgets.QuickCreate'
this.controllerParams.quickAddPop = (!('quick_add' in attrs) || utils.toBoolElse(attrs.quick_add+'', true));
this.controllerParams.disableQuickCreate = params.disable_quick_create || !this.controllerParams.quickAddPop;
- // If this field is set ot true, we don't open the event in form view, but in a popup with the view_id passed by this parameter
- this.controllerParams.formViewId = !attrs.form_view_id || !utils.toBoolElse(attrs.form_view_id, true) ? false : attrs.form_view_id;
+
+ // If form_view_id is set, then the calendar view will open a form view
+ // with this id, when it needs to edit or create an event.
+ this.controllerParams.formViewId =
+ attrs.form_view_id ? parseInt(attrs.form_view_id, 10) : false;
+ if (!this.controllerParams.formViewId && params.action) {
+ var formViewDescr = _.find(params.action.views, function (v) {
+ return v[1] === 'form';
+ });
+ if (formViewDescr) {
+ this.controllerParams.formViewId = formViewDescr[0];
+ }
+ }
+
this.controllerParams.readonlyFormViewId = !attrs.readonly_form_view_id || !utils.toBoolElse(attrs.readonly_form_view_id, true) ? false : attrs.readonly_form_view_id;
this.controllerParams.eventOpenPopup = utils.toBoolElse(attrs.event_open_popup || '', false);
this.controllerParams.mapping = mapping;
diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js
index e66194dcf99..3fefd7ca173 100644
--- a/addons/web/static/src/js/views/form/form_controller.js
+++ b/addons/web/static/src/js/views/form/form_controller.js
@@ -232,6 +232,16 @@ var FormController = BasicController.extend({
return changedFields;
});
},
+ /**
+ * Overrides to force the viewType to 'form', so that we ensure that the
+ * correct fields are reloaded (this is only useful for one2many form views).
+ *
+ * @override
+ */
+ update: function (params, options) {
+ params = _.extend({viewType: 'form'}, params);
+ return this._super(params, options);
+ },
//--------------------------------------------------------------------------
// Private
diff --git a/addons/web/static/src/js/views/form/form_view.js b/addons/web/static/src/js/views/form/form_view.js
index 10fc9a12b20..d8693586590 100644
--- a/addons/web/static/src/js/views/form/form_view.js
+++ b/addons/web/static/src/js/views/form/form_view.js
@@ -73,6 +73,14 @@ var FormView = BasicView.extend({
_.each(this.loadParams.fieldsInfo.form, function (attrs, fieldName) {
var field = fields[fieldName];
+ if (!field) {
+ // when a one2many record is opened in a form view, the fields
+ // of the main one2many view (list or kanban) are added to the
+ // fieldsInfo of its form view, but those fields aren't in the
+ // loadParams.fields, as they are not displayed in the view, so
+ // we can ignore them.
+ return;
+ }
if (field.type !== 'one2many' && field.type !== 'many2many') {
return;
}
diff --git a/addons/web/static/src/js/views/kanban/kanban_model.js b/addons/web/static/src/js/views/kanban/kanban_model.js
index 411d4cc7b14..6c4ea1f133c 100644
--- a/addons/web/static/src/js/views/kanban/kanban_model.js
+++ b/addons/web/static/src/js/views/kanban/kanban_model.js
@@ -398,9 +398,8 @@ var KanbanModel = BasicModel.extend({
return $.when();
},
/**
- * Reloads all progressbar data if the given id is a record's one. This is
- * done after given deferred and insures that the given deferred's result is
- * not lost.
+ * Reloads all progressbar data. This is done after given deferred and
+ * insures that the given deferred's result is not lost.
*
* @private
* @param {string} recordID
@@ -409,7 +408,9 @@ var KanbanModel = BasicModel.extend({
*/
_reloadProgressBarGroupFromRecord: function (recordID, def) {
var element = this.localData[recordID];
- if (element.type !== 'record') {
+ if (element.type === 'list' && !element.parentID) {
+ // we are reloading the whole view, so there is no need to manually
+ // reload the progressbars
return def;
}
diff --git a/addons/web/static/src/js/views/list/list_editable_renderer.js b/addons/web/static/src/js/views/list/list_editable_renderer.js
index f3dc79cd4bf..a12b85abdd0 100644
--- a/addons/web/static/src/js/views/list/list_editable_renderer.js
+++ b/addons/web/static/src/js/views/list/list_editable_renderer.js
@@ -538,8 +538,13 @@ ListRenderer.include({
* @returns {Deferred} this deferred is resolved immediately
*/
_renderView: function () {
+ var self = this;
this.currentRow = null;
- return this._super.apply(this, arguments);
+ return this._super.apply(this, arguments).then(function () {
+ if (self._isEditable()) {
+ self.$('table').addClass('o_editable_list');
+ }
+ });
},
/**
* Force the resequencing of the items in the list.
diff --git a/addons/web/static/src/js/views/pivot/pivot_model.js b/addons/web/static/src/js/views/pivot/pivot_model.js
index 4a5d9b45b4a..b45f7a9ffdf 100644
--- a/addons/web/static/src/js/views/pivot/pivot_model.js
+++ b/addons/web/static/src/js/views/pivot/pivot_model.js
@@ -17,6 +17,7 @@ odoo.define('web.PivotModel', function (require) {
*/
var AbstractModel = require('web.AbstractModel');
+var concurrency = require('web.concurrency');
var core = require('web.core');
var session = require('web.session');
var utils = require('web.utils');
@@ -32,6 +33,7 @@ var PivotModel = AbstractModel.extend({
this._super.apply(this, arguments);
this.numbering = {};
this.data = null;
+ this._loadDataDropPrevious = new concurrency.DropPrevious();
},
//--------------------------------------------------------------------------
@@ -556,7 +558,7 @@ var PivotModel = AbstractModel.extend({
}
}
- return $.when.apply(null, groupBys.map(function (groupBy) {
+ return this._loadDataDropPrevious.add($.when.apply(null, groupBys.map(function (groupBy) {
return self._rpc({
model: self.modelName,
method: 'read_group',
@@ -566,7 +568,7 @@ var PivotModel = AbstractModel.extend({
groupBy: groupBy,
lazy: false,
});
- })).then(function () {
+ }))).then(function () {
var data = Array.prototype.slice.call(arguments);
if (data[0][0].__count === 0) {
self.data.has_data = false;
diff --git a/addons/web/static/src/less/list_view.less b/addons/web/static/src/less/list_view.less
index b5237d305cb..666b4a8e116 100644
--- a/addons/web/static/src/less/list_view.less
+++ b/addons/web/static/src/less/list_view.less
@@ -6,6 +6,14 @@
background-color: @odoo-view-background-color;
margin-bottom: 0px;
+ // Checkbox in editable list
+ // should be clickable and activate the row
+ &.o_editable_list .o_data_row:not(.o_selected_row) .o_data_cell {
+ .o_checkbox:not(.o_readonly_modifier) {
+ pointer-events: none;
+ }
+ }
+
&.table {
td, th {
vertical-align: middle;