diff options
| author | Christophe Simonis <chs@odoo.com> | 2018-10-22 17:57:08 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2018-10-22 17:57:08 +0200 |
| commit | 9dbb7d199cfe085ea5e3a4980de2bd766953ab93 (patch) | |
| tree | 6ed48459069117f9f2cbd0fffa771c907592bb38 /addons/web/static/src/js/views | |
| parent | a8cec47c930c1d3b60f0e5c5788106cc30dc1a0b (diff) | |
| parent | b81c2bce846c94b5695d680ebbc30f1cfe51e614 (diff) | |
[MERGE] forward port branch 12.0 up to b81c2bce846
Diffstat (limited to 'addons/web/static/src/js/views')
12 files changed, 140 insertions, 71 deletions
diff --git a/addons/web/static/src/js/views/abstract_view.js b/addons/web/static/src/js/views/abstract_view.js index 7705ee5972e..f3277d394a3 100644 --- a/addons/web/static/src/js/views/abstract_view.js +++ b/addons/web/static/src/js/views/abstract_view.js @@ -308,3 +308,55 @@ var AbstractView = Class.extend({ return AbstractView; }); + +odoo.define('web.viewUtils', function () { +"use strict"; + +/** + * FIXME: move this module to its own file in master + */ + +var utils = { + /** + * Returns the value of a group dataPoint, i.e. the value of the groupBy + * field for the records in that group. + * + * @param {Object} group dataPoint of type list, corresponding to a group + * @param {string} groupByField the name of the groupBy field + * @returns {string | integer | false} + */ + getGroupValue: function (group, groupByField) { + var groupedByField = group.fields[groupByField]; + switch (groupedByField.type) { + case 'many2one': + return group.res_id || false; + case 'selection': + var descriptor = _.findWhere(groupedByField.selection, group.value); + return descriptor && descriptor[0]; + default: + return group.value; + } + }, + /** + * States whether or not the quick create feature is available for the given + * datapoint, depending on its groupBy field. + * + * @param {Object} list dataPoint of type list + * @returns {Boolean} true iff the kanban quick create feature is available + */ + isQuickCreateEnabled: function (list) { + var groupByField = list.groupedBy[0] && list.groupedBy[0].split(':')[0]; + if (!groupByField) { + return false; + } + var availableTypes = ['char', 'boolean', 'many2one', 'selection']; + if (!_.contains(availableTypes, list.fields[groupByField].type)) { + return false; + } + return true; + }, +}; + +return utils; + +}); 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 f6bf46aed68..de879018ad5 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -398,8 +398,14 @@ var BasicModel = AbstractModel.extend({ // by 1 (at least until there is a gap in the numbering). // We don't do it now because it's not an important case. + // However, we can for sure increment by 1 if we are on the last page. + var handleFieldValue = computedList.data[index].data[handleField]; - handleFieldValue = position !== 'top' ? handleFieldValue : handleFieldValue - 1; + if (position === 'top') { + handleFieldValue--; + } else if (list.count <= list.offset + list.limit - (list.tempLimitIncrement || 0)) { + handleFieldValue++; + } return { field: handleField, @@ -1010,27 +1016,51 @@ var BasicModel = AbstractModel.extend({ route: '/web/dataset/resequence', params: params, }) - .then(function () { - var offset = options.offset ? options.offset : 0; - var old_data = data.data.slice(); - data.data = _.sortBy(data.data, function (d) { - if (_.contains(resIDs, self.localData[d].res_id)) { - return _.indexOf(resIDs, self.localData[d].res_id) + offset; - } else { - return _.indexOf(old_data, d); - } - }); - data.res_ids = []; - _.each(data.data, function (d) { - var dataPoint = self.localData[d]; - if (dataPoint.type === 'record') { - data.res_ids.push(dataPoint.res_id); - } else { - data.res_ids = data.res_ids.concat(dataPoint.res_ids); + .then(function (wasResequenced) { + if (!wasResequenced) { + // the field on which the resequence was triggered does not + // exist, so no resequence happened server-side + return $.when(); + } + var field = params.field ? params.field : 'sequence'; + + return self._rpc({ + model: modelName, + method: 'read', + args: [resIDs, [field]], + }).then(function (records) { + if (data.data.length) { + var dataType = self.localData[data.data[0]].type; + if (dataType === 'record') { + _.each(data.data, function (dataPoint) { + var recordData = self.localData[dataPoint].data; + var inRecords = _.findWhere(records, {id: recordData.id}); + if (inRecords) { + recordData[field] = inRecords[field]; + } + }); + data.data = _.sortBy(data.data, function (d) { + return self.localData[d].data[field]; + }); + } + if (dataType === 'list') { + data.data = _.sortBy(data.data, function (d) { + return _.indexOf(resIDs, self.localData[d].res_id) + }); + } } - }); - self._updateParentResIDs(data); - return parentID; + data.res_ids = []; + _.each(data.data, function (d) { + var dataPoint = self.localData[d]; + if (dataPoint.type === 'record') { + data.res_ids.push(dataPoint.res_id); + } else { + data.res_ids = data.res_ids.concat(dataPoint.res_ids); + } + }); + self._updateParentResIDs(data); + return parentID; + }) }); }, /** diff --git a/addons/web/static/src/js/views/basic/basic_view.js b/addons/web/static/src/js/views/basic/basic_view.js index 7bc5e95bfc8..9e1cde2aada 100644 --- a/addons/web/static/src/js/views/basic/basic_view.js +++ b/addons/web/static/src/js/views/basic/basic_view.js @@ -225,7 +225,7 @@ var BasicView = AbstractView.extend({ attrs.options = attrs.options ? pyUtils.py_eval(attrs.options) : {}; } - if (attrs.on_change && !field.onChange) { + if (attrs.on_change && attrs.on_change !== "0" && !field.onChange) { field.onChange = "1"; } @@ -378,6 +378,10 @@ var BasicView = AbstractView.extend({ if (!(dependency_name in fields)) { fields[dependency_name] = dependency_dict; } + + if (fv.fields && !(dependency_name in fv.fields)) { + fv.fields[dependency_name] = dependency_dict; + } } } return false; diff --git a/addons/web/static/src/js/views/calendar/calendar_renderer.js b/addons/web/static/src/js/views/calendar/calendar_renderer.js index e76a487b73b..c2c90ea7e62 100644 --- a/addons/web/static/src/js/views/calendar/calendar_renderer.js +++ b/addons/web/static/src/js/views/calendar/calendar_renderer.js @@ -77,9 +77,9 @@ var SidebarFilter = Widget.extend(FieldManagerMixin, { self.model.get(recordID), { mode: 'edit', - can_create: false, attrs: { - 'placeholder': _.str.sprintf(_t("Add %s"), self.title), + placeholder: _.str.sprintf(_t("Add %s"), self.title), + can_create: false }, }); }); diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js index 190fbe88ad2..c7a32b72ba9 100644 --- a/addons/web/static/src/js/views/form/form_renderer.js +++ b/addons/web/static/src/js/views/form/form_renderer.js @@ -995,10 +995,7 @@ var FormRenderer = BasicRenderer.extend({ * @param {OdooEvent} ev */ _onNavigationMove: function (ev) { - if (ev.data.direction !== "cancel") { - ev.stopPropagation(); - } - + ev.stopPropagation(); var index; if (ev.data.direction === "next") { index = this.allFieldWidgets[this.state.id].indexOf(ev.data.target || ev.target); diff --git a/addons/web/static/src/js/views/graph/graph_renderer.js b/addons/web/static/src/js/views/graph/graph_renderer.js index f923ade149b..0517e14c876 100644 --- a/addons/web/static/src/js/views/graph/graph_renderer.js +++ b/addons/web/static/src/js/views/graph/graph_renderer.js @@ -341,7 +341,6 @@ return AbstractRenderer.extend({ var data = []; var ticksLabels = []; - var tickValues = []; var measure = this.state.fields[this.state.measure].string; var values; @@ -363,18 +362,6 @@ return AbstractRenderer.extend({ key: measure + ' (compare)', color: '#ff7f0e', }); - - if (this.state.comparisonData.length > graphData.length) { - tickValues = this.state.comparisonData.map(function (d, i) { - return i; - }); - } - } - - if (!tickValues.length) { - tickValues = graphData.map(function (d, i) { - return i; - }); } for (i = 0; i < graphData.length; i++) { @@ -403,7 +390,6 @@ return AbstractRenderer.extend({ for (var i = 0; i < this.state.data.length; i++) { if (graphData[i].labels[0] !== tickLabel) { tickLabel = this.state.data[i].labels[0]; - tickValues.push(tick); ticksLabels.push(tickLabel); tick++; } @@ -438,7 +424,6 @@ return AbstractRenderer.extend({ }); chart.forceY([0]); chart.xAxis - .tickValues(tickValues) .tickFormat(function (d) { return ticksLabels[d]; }); @@ -491,19 +476,6 @@ return AbstractRenderer.extend({ $('.nv-y .tick > line').attr('x2', function (i, value) { return Math.abs(value); }); - - // We don't need to show all labels - $('.o_graph_svg_container svg .nv-x g.tick > text').show(); - var $ticksText = $('svg .nv-x g.tick:not(.zero) > text'); - var ticksLength = $ticksText.length; - var tickTextMargin = 5; - if (ticksLength) { - var tickWidth = $ticksText[0].getBBox().width + tickTextMargin; - var svgWidth = $('.o_graph_svg_container').width(); - var keepOneOf = Math.ceil(ticksLength / (svgWidth / tickWidth)); - // FIXME: should work with two line charts - $('.o_graph_svg_container svg .nv-x g.tick:not(:nth-child(' + keepOneOf + 'n+1)) > text').hide(); - } }) chartResize(chart); diff --git a/addons/web/static/src/js/views/kanban/kanban_column.js b/addons/web/static/src/js/views/kanban/kanban_column.js index ef75caca8c0..ffb63ad9083 100644 --- a/addons/web/static/src/js/views/kanban/kanban_column.js +++ b/addons/web/static/src/js/views/kanban/kanban_column.js @@ -7,6 +7,7 @@ var Dialog = require('web.Dialog'); var KanbanRecord = require('web.KanbanRecord'); var RecordQuickCreate = require('web.kanban_record_quick_create'); var view_dialogs = require('web.view_dialogs'); +var viewUtils = require('web.viewUtils'); var Widget = require('web.Widget'); var KanbanColumnProgressBar = require('web.KanbanColumnProgressBar'); @@ -201,7 +202,7 @@ var KanbanColumn = Widget.extend({ this.trigger_up('close_quick_create'); // close other quick create widgets this.trigger_up('start_quick_create'); var context = this.data.getContext(); - context['default_' + this.groupedBy] = this.id; + context['default_' + this.groupedBy] = viewUtils.getGroupValue(this.data, this.groupedBy); this.quickCreateWidget = new RecordQuickCreate(this, { context: context, formViewRef: this.quickCreateView, diff --git a/addons/web/static/src/js/views/kanban/kanban_controller.js b/addons/web/static/src/js/views/kanban/kanban_controller.js index 9599d29db26..e195b33068c 100644 --- a/addons/web/static/src/js/views/kanban/kanban_controller.js +++ b/addons/web/static/src/js/views/kanban/kanban_controller.js @@ -12,6 +12,7 @@ var Context = require('web.Context'); var core = require('web.core'); var Domain = require('web.Domain'); var view_dialogs = require('web.view_dialogs'); +var viewUtils = require('web.viewUtils'); var _t = core._t; var qweb = core.qweb; @@ -35,12 +36,15 @@ var KanbanController = BasicController.extend({ /** * @override * @param {Object} params + * @param {boolean} params.quickCreateEnabled set to false to disable the + * quick create feature */ init: function (parent, model, renderer, params) { this._super.apply(this, arguments); this.on_create = params.on_create; this.hasButtons = params.hasButtons; + this.quickCreateEnabled = params.quickCreateEnabled; }, //-------------------------------------------------------------------------- @@ -268,8 +272,8 @@ var KanbanController = BasicController.extend({ */ _onButtonNew: function () { var state = this.model.get(this.handle, {raw: true}); - var hasColumns = state.groupedBy.length > 0 && state.data.length > 0; - if (hasColumns && this.on_create === 'quick_create') { + var quickCreateEnabled = this.quickCreateEnabled && viewUtils.isQuickCreateEnabled(state); + if (this.on_create === 'quick_create' && quickCreateEnabled) { // Activate the quick create in the first column this.renderer.addQuickCreate(); } else if (this.on_create && this.on_create !== 'quick_create') { @@ -396,10 +400,11 @@ var KanbanController = BasicController.extend({ var columnState = self.model.get(column.db_id, {raw: true}); var context = columnState.getContext(); var state = self.model.get(self.handle, {raw: true}); - context['default_' + state.groupedBy[0]] = columnState.res_id; + var groupedBy = state.groupedBy[0]; + context['default_' + groupedBy] = viewUtils.getGroupValue(columnState, groupedBy); new view_dialogs.FormViewDialog(self, { res_model: state.model, - context: _.extend({default_name: name}, context), + context: _.extend({default_name: values.name || values.display_name}, context), title: _t("Create"), disable_multiple_selection: true, on_saved: function (record) { 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 905ea05ac1e..fd21ed4df86 100644 --- a/addons/web/static/src/js/views/kanban/kanban_model.js +++ b/addons/web/static/src/js/views/kanban/kanban_model.js @@ -7,6 +7,7 @@ odoo.define('web.KanbanModel', function (require) { */ var BasicModel = require('web.BasicModel'); +var viewUtils = require('web.viewUtils'); var KanbanModel = BasicModel.extend({ @@ -105,7 +106,8 @@ var KanbanModel = BasicModel.extend({ var group = this.localData[groupID]; var context = this._getContext(group); var parent = this.localData[group.parentID]; - context['default_' + parent.groupedBy[0]] = group.res_id; + var groupedBy = parent.groupedBy; + context['default_' + groupedBy] = viewUtils.getGroupValue(group, groupedBy); var def; if (Object.keys(values).length === 1 && 'display_name' in values) { // only 'display_name is given, perform a 'name_create' @@ -132,7 +134,7 @@ var KanbanModel = BasicModel.extend({ }, /** * Add the following (kanban specific) keys when performing a `get`: - * + * * - tooltipData * - progressBarValues * - isGroupedByM2ONoColumn diff --git a/addons/web/static/src/js/views/kanban/kanban_record.js b/addons/web/static/src/js/views/kanban/kanban_record.js index 7013464ea87..d9d7ac77fe2 100644 --- a/addons/web/static/src/js/views/kanban/kanban_record.js +++ b/addons/web/static/src/js/views/kanban/kanban_record.js @@ -509,10 +509,12 @@ var KanbanRecord = Widget.extend({ ischild = false; } var test_event = events && events.click && (events.click.length > 1 || events.click[0].namespace !== 'bs.tooltip'); + var testLinkWithHref = elem.nodeName.toLowerCase() === 'a' && elem.href; if (ischild) { children.push(elem); - if (test_event) { - // do not trigger global click if one child has a click event registered + if (test_event || testLinkWithHref) { + // Do not trigger global click if one child has a click + // event registered (or it is a link with href) trigger = false; } } diff --git a/addons/web/static/src/js/views/kanban/kanban_renderer.js b/addons/web/static/src/js/views/kanban/kanban_renderer.js index c51ac945de1..9356311d51c 100644 --- a/addons/web/static/src/js/views/kanban/kanban_renderer.js +++ b/addons/web/static/src/js/views/kanban/kanban_renderer.js @@ -9,6 +9,7 @@ var ColumnQuickCreate = require('web.kanban_column_quick_create'); var QWeb = require('web.QWeb'); var session = require('web.session'); var utils = require('web.utils'); +var viewUtils = require('web.viewUtils'); var qweb = core.qweb; @@ -98,6 +99,9 @@ var KanbanRenderer = BasicRenderer.extend({ /** * @override + * @param {Object} params + * @param {boolean} params.quickCreateEnabled set to false to disable the + * quick create feature */ init: function (parent, state, params) { this._super.apply(this, arguments); @@ -116,6 +120,7 @@ var KanbanRenderer = BasicRenderer.extend({ if (this.columnOptions.hasProgressBar) { this.columnOptions.progressBarStates = {}; } + this.quickCreateEnabled = params.quickCreateEnabled; this._setState(state); }, /** @@ -453,6 +458,7 @@ var KanbanRenderer = BasicRenderer.extend({ groupedBy: groupByField, grouped_by_m2o: this.groupedByM2O, relation: relation, + quick_create: this.quickCreateEnabled && viewUtils.isQuickCreateEnabled(state), }); this.createColumnEnabled = this.groupedByM2O && this.columnOptions.group_creatable; }, diff --git a/addons/web/static/src/js/views/kanban/kanban_view.js b/addons/web/static/src/js/views/kanban/kanban_view.js index 791e3664668..523f0ef1c57 100644 --- a/addons/web/static/src/js/views/kanban/kanban_view.js +++ b/addons/web/static/src/js/views/kanban/kanban_view.js @@ -63,7 +63,6 @@ var KanbanView = BasicView.extend({ deletable: activeActions.group_delete, archivable: this.arch.attrs.archivable ? JSON.parse(this.arch.attrs.archivable) : true, group_creatable: activeActions.group_create && !config.device.isMobile, - quick_create: params.isQuickCreateEnabled || this._isQuickCreateEnabled(), quickCreateView: this.arch.attrs.quick_create_view || null, hasProgressBar: !!progressBar, }; @@ -72,6 +71,7 @@ var KanbanView = BasicView.extend({ deletable: activeActions.delete, read_only_mode: params.readOnlyMode, }; + this.rendererParams.quickCreateEnabled = this._isQuickCreateEnabled(); var examples = this.arch.attrs.examples; if (examples) { this.rendererParams.examples = kanbanExamplesRegistry.get(examples); @@ -80,6 +80,7 @@ var KanbanView = BasicView.extend({ this.controllerParams.on_create = this.arch.attrs.on_create; this.controllerParams.readOnlyMode = false; this.controllerParams.hasButtons = true; + this.controllerParams.quickCreateEnabled = this.rendererParams.quickCreateEnabled; if (config.device.isMobile) { this.jsLibs.push('/web/static/lib/jquery.touchSwipe/jquery.touchSwipe.js'); @@ -93,13 +94,10 @@ var KanbanView = BasicView.extend({ /** * @private * @param {Object} viewInfo + * @returns {boolean} true iff the quick create feature is not explicitely + * disabled (with create="False" or quick_create="False" in the arch) */ _isQuickCreateEnabled: function () { - var groupBy = this.loadParams.groupBy[0]; - groupBy = groupBy !== undefined ? groupBy.split(':')[0] : undefined; - if (groupBy !== undefined && !_.contains(['char', 'boolean', 'many2one'], this.fields[groupBy].type)) { - return false; - } if (!this.controllerParams.activeActions.create) { return false; } |
