From d82a9077289ea21bf10717d829e0853418cf09eb Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Wed, 17 Oct 2018 10:07:41 +0200 Subject: [PATCH] [FIX] web: kanban quick create when grouped by selection Rev. 42e1efded5 aimed to disable the quick create feature when grouped by date(time) fields, by only enabling it for char, boolean and many2one fields. However, the selection case is quite important and must be handled as well. This is what this rev. does. Task 1878254 --- .../web/static/src/js/views/abstract_view.js | 22 ++- .../src/js/views/kanban/kanban_column.js | 3 +- .../src/js/views/kanban/kanban_controller.js | 3 +- .../src/js/views/kanban/kanban_model.js | 7 +- addons/web/static/tests/views/kanban_tests.js | 139 ++++++++++++++++++ doc/reference/views.rst | 2 +- 6 files changed, 168 insertions(+), 8 deletions(-) diff --git a/addons/web/static/src/js/views/abstract_view.js b/addons/web/static/src/js/views/abstract_view.js index a8e4ebbd8f0..9b6e5a5d192 100644 --- a/addons/web/static/src/js/views/abstract_view.js +++ b/addons/web/static/src/js/views/abstract_view.js @@ -282,6 +282,26 @@ odoo.define('web.viewUtils', function () { */ 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. @@ -294,7 +314,7 @@ var utils = { if (!groupByField) { return false; } - var availableTypes = ['char', 'boolean', 'many2one']; + var availableTypes = ['char', 'boolean', 'many2one', 'selection']; if (!_.contains(availableTypes, list.fields[groupByField].type)) { return false; } 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 15f37551188..8cc33aa32d0 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'); @@ -194,7 +195,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.grouped_by_m2o ? this.id : this.data.value; + 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 025cbc79247..7f44dceb2ef 100644 --- a/addons/web/static/src/js/views/kanban/kanban_controller.js +++ b/addons/web/static/src/js/views/kanban/kanban_controller.js @@ -389,8 +389,7 @@ var KanbanController = BasicController.extend({ var context = columnState.getContext(); var state = self.model.get(self.handle, {raw: true}); var groupedBy = state.groupedBy[0]; - var groupedByM2O = state.fields[groupedBy].type === 'many2one'; - context['default_' + groupedBy] = groupedByM2O ? columnState.res_id : columnState.value; + context['default_' + groupedBy] = viewUtils.getGroupValue(columnState, groupedBy); new view_dialogs.FormViewDialog(self, { res_model: state.model, context: _.extend({default_name: values.name || values.display_name}, context), 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 b71a11f08ec..5dfa0b8a75d 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,8 +106,8 @@ var KanbanModel = BasicModel.extend({ var group = this.localData[groupID]; var context = this._getContext(group); var parent = this.localData[group.parentID]; - var groupedByM2O = parent.fields[parent.groupedBy].type === 'many2one'; - context['default_' + parent.groupedBy[0]] = groupedByM2O ? group.res_id : group.value; + 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' @@ -133,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/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js index 3b0a48f9445..f50d1cd18b2 100644 --- a/addons/web/static/tests/views/kanban_tests.js +++ b/addons/web/static/tests/views/kanban_tests.js @@ -1233,6 +1233,63 @@ QUnit.module('Views', { kanban.destroy(); }); + QUnit.test('quick create record fails in grouped by selection', function (assert) { + assert.expect(7); + + var kanban = createView({ + View: KanbanView, + model: 'partner', + data: this.data, + arch: '' + + '' + + '
' + + '
' + + '
', + archs: { + 'partner,false,form': '
' + + '' + + '', + }, + mockRPC: function (route, args) { + if (args.method === 'name_create') { + return $.Deferred().reject({ + code: 200, + data: {}, + message: "Odoo server error", + }, $.Event()); + } + if (args.method === 'create') { + assert.deepEqual(args.args[0], {state: 'abc'}, + "should write the correct value for state"); + assert.deepEqual(args.kwargs.context, {default_state: 'abc', default_name: 'test'}, + "should send the correct default value for state"); + } + return this._super.apply(this, arguments); + }, + groupBy: ['state'], + }); + + assert.strictEqual(kanban.$('.o_kanban_group:first .o_kanban_record').length, 1, + "there should be 1 record in first column"); + + kanban.$('.o_kanban_header:first .o_kanban_quick_add i').click(); + kanban.$('.o_kanban_quick_create input').val('test').trigger('input'); + kanban.$('.o_kanban_add').click(); + + assert.strictEqual($('.modal .o_form_view.o_form_editable').length, 1, + "a form view dialog should have been opened (in edit)"); + assert.strictEqual($('.modal .o_field_widget[name=state]').val(), '"abc"', + "the correct default value for state should already be set"); + + $('.modal-footer .btn-primary').click(); + + assert.strictEqual($('.modal').length, 0, "the modal should be closed"); + assert.strictEqual(kanban.$('.o_kanban_group:first .o_kanban_record').length, 2, + "there should be 2 records in first column"); + + kanban.destroy(); + }); + QUnit.test('quick create record in empty grouped kanban', function (assert) { assert.expect(3); @@ -1424,6 +1481,43 @@ QUnit.module('Views', { kanban.destroy(); }); + QUnit.test('quick create record in grouped on selection field', function (assert) { + assert.expect(4); + + var kanban = createView({ + View: KanbanView, + model: 'partner', + data: this.data, + arch: '' + + '' + + '
' + + '
' + + '
', + mockRPC: function (route, args) { + if (args.method === 'name_create') { + assert.deepEqual(args.kwargs.context, {default_state: 'abc'}, + "should send the correct default value for bar"); + } + return this._super.apply(this, arguments); + }, + groupBy: ['state'], + }); + + assert.strictEqual(kanban.$('.o_kanban_header .o_kanban_quick_add i').length, 3, + "quick create should be enabled when grouped on a selection field"); + assert.strictEqual(kanban.$('.o_kanban_group:first .o_kanban_record').length, 1, + "first column (abc) should contain 1 record"); + + kanban.$('.o_kanban_header:first .o_kanban_quick_add i').click(); + kanban.$('.o_kanban_quick_create input').val('new record').trigger('input'); + kanban.$('.o_kanban_add').click(); + + assert.strictEqual(kanban.$('.o_kanban_group:first .o_kanban_record').length, 2, + "first column (abc) should contain 2 records"); + + kanban.destroy(); + }); + QUnit.test('quick create record in grouped by char field (within quick_create_view)', function (assert) { assert.expect(6); @@ -1514,6 +1608,51 @@ QUnit.module('Views', { kanban.destroy(); }); + QUnit.test('quick create record in grouped by selection field (within quick_create_view)', function (assert) { + assert.expect(6); + + var kanban = createView({ + View: KanbanView, + model: 'partner', + data: this.data, + arch: '' + + '' + + '
' + + '
' + + '
', + archs: { + 'partner,some_view_ref,form': '
' + + '' + + '', + }, + groupBy: ['state'], + mockRPC: function (route, args) { + if (args.method === 'create') { + assert.deepEqual(args.args[0], {state: 'abc'}, + "should write the correct value for state"); + assert.deepEqual(args.kwargs.context, {default_state: 'abc'}, + "should send the correct default value for state"); + } + return this._super.apply(this, arguments); + }, + }); + + assert.strictEqual(kanban.$('.o_kanban_header .o_kanban_quick_add i').length, 3, + "quick create should be enabled when grouped on a selection field"); + assert.strictEqual(kanban.$('.o_kanban_group:first .o_kanban_record').length, 1, + "first column (abc) should contain 1 record"); + + kanban.$('.o_kanban_header:first .o_kanban_quick_add i').click(); + assert.strictEqual(kanban.$('.o_kanban_quick_create select').val(), '"abc"', + "should have set the correct state value by default"); + kanban.$('.o_kanban_add').click(); + + assert.strictEqual(kanban.$('.o_kanban_group:first .o_kanban_record').length, 2, + "first column (abc) should now contain 2 records"); + + kanban.destroy(); + }); + QUnit.test('many2many_tags in kanban views', function (assert) { assert.expect(12); diff --git a/doc/reference/views.rst b/doc/reference/views.rst index d35af9b7b36..42fcc86d047 100644 --- a/doc/reference/views.rst +++ b/doc/reference/views.rst @@ -852,7 +852,7 @@ attributes: ``quick_create`` whether it should be possible to create records without switching to the form view. By default, ``quick_create`` is enabled when the Kanban view is - grouped by many2one, char or boolean fields, and disabled when not. + grouped by many2one, selection, char or boolean fields, and disabled when not. Set to ``true`` to always enable it, and to ``false`` to always disable it.