diff --git a/addons/web/static/src/js/services/data_manager.js b/addons/web/static/src/js/services/data_manager.js index 4786515bb15..cf49dd3aaec 100644 --- a/addons/web/static/src/js/services/data_manager.js +++ b/addons/web/static/src/js/services/data_manager.js @@ -304,6 +304,18 @@ return core.Class.extend({ viewType = viewType === 'tree' ? 'list' : viewType; innerFieldsView.type = viewType; attrs.views[viewType] = self._processFieldsView(_.extend({}, innerFieldsView)); + + // default_order is like: + // 'name,id desc' + // but we need it like: + // [{name: 'id', asc: false}, {name: 'name', asc: true}] + var defaultOrder = innerFieldsView.arch.attrs.default_order; + if (defaultOrder) { + attrs.orderedBy = _.map(defaultOrder.split(','), function (order) { + order = order.split(' '); + return {name: order[0], asc: order[1] !== 'desc'}; + }); + } }); delete field.views; } diff --git a/addons/web/static/src/js/views/abstract_view.js b/addons/web/static/src/js/views/abstract_view.js index f4def9f69c8..af3e36ad45b 100644 --- a/addons/web/static/src/js/views/abstract_view.js +++ b/addons/web/static/src/js/views/abstract_view.js @@ -102,6 +102,17 @@ var AbstractView = Class.extend({ if (params.modelName) { this.loadParams.modelName = params.modelName; } + // default_order is like: + // 'name,id desc' + // but we need it like: + // [{name: 'id', asc: false}, {name: 'name', asc: true}] + var defaultOrder = viewInfo.arch.attrs.default_order; + if (defaultOrder) { + this.loadParams.orderedBy = _.map(defaultOrder.split(','), function (order) { + order = order.split(' '); + return {name: order[0], asc: order[1] !== 'desc'}; + }); + } this.userContext = params.userContext; }, 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 ef93028eeba..f7026f27129 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -37,7 +37,7 @@ odoo.define('web.BasicModel', function (require) { * model: {string, * offset: {integer}, * openGroupByDefault: {boolean}, - * orderedBy: {string[]}, + * orderedBy: {Object[]}, * parentID: {string}, * rawContext: {Object}, * relationField: {string}, @@ -1621,6 +1621,7 @@ var BasicModel = AbstractModel.extend({ res_ids: ids, static: true, type: 'list', + orderedBy: fieldInfo.orderedBy, parentID: record.id, rawContext: rawContext, relationField: field.relation_field, diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index b6d416156aa..f09d98d641e 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -3990,5 +3990,33 @@ QUnit.module('Views', { form.destroy(); }); + + QUnit.test('default_order on x2many embedded view', function (assert) { + assert.expect(1); + + this.data.partner.records[0].p = [1, 4]; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
', + res_id: 1, + }); + + assert.ok(form.$('.o_form_field_one2many tbody tr:first td:contains(yop)').length, + "record 1 should be first"); + + form.destroy(); + }); }); }); diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js index 50d5fbd7182..beb3b1843b1 100644 --- a/addons/web/static/tests/views/list_tests.js +++ b/addons/web/static/tests/views/list_tests.js @@ -664,6 +664,31 @@ QUnit.module('Views', { list.destroy(); }); + QUnit.test('use default_order', function (assert) { + assert.expect(3); + + var list = createView({ + View: ListView, + model: 'foo', + data: this.data, + arch: '', + mockRPC: function (route, args) { + if (route === '/web/dataset/search_read') { + assert.strictEqual(args.sort, 'foo ASC', + "should correctly set the sort attribute"); + } + return this._super.apply(this, arguments); + }, + }); + + assert.ok(list.$('tbody tr:first td:contains(blip)').length, + "record 3 should be first"); + assert.ok(list.$('tbody tr:eq(3) td:contains(yop)').length, + "record 1 should be first"); + + list.destroy(); + }); + QUnit.test('can display button in edit mode', function (assert) { assert.expect(1);