[FIX] web: implement filter orderedBy
related to: #28446 On a pure list view, click on a column to sort the records by that field. Save the filter as favorite Reload, now apply the filter Before this commit, there were two issues: 1. The order of the list was never propagated to search view, which couldn't save the filter with its attribute "sort" 2. There was no mechanism to load the attribute sort from a loading Filter After this commit, those two issues are corrected Unfortunately, complex search view flows are not testable in v11.0 OPW 1906968 closes odoo/odoo#28766
This commit is contained in:
@@ -100,9 +100,17 @@ return Widget.extend({
|
||||
var controllerContext;
|
||||
this.trigger_up('get_controller_context', {
|
||||
callback: function (ctx) {
|
||||
controllerContext = ctx;
|
||||
if (ctx && ctx.orderedBy) {
|
||||
var sort = _.map(ctx.orderedBy, function (obj) {
|
||||
var order = obj.asc ? 'ASC' : 'DESC';
|
||||
return obj.name + ' ' + order;
|
||||
});
|
||||
self.searchview.dataset.set_sort(sort);
|
||||
}
|
||||
controllerContext = _.omit(ctx, ['orderedBy']);
|
||||
},
|
||||
});
|
||||
|
||||
var results = pyeval.eval_domains_and_contexts({
|
||||
domains: search.domains,
|
||||
contexts: [user_context].concat(search.contexts.concat(controllerContext || [])),
|
||||
@@ -182,7 +190,18 @@ return Widget.extend({
|
||||
category: _t("Custom Filter"),
|
||||
icon: 'fa-star',
|
||||
field: {
|
||||
get_context: function () { return filter.context; },
|
||||
get_context: function () {
|
||||
var sortParsed = JSON.parse(filter.sort || "[]");
|
||||
var orderedBy = [];
|
||||
_.each(sortParsed, function (sort) {
|
||||
orderedBy.push({
|
||||
name: sort[0] === '-' ? sort.slice(1) : sort,
|
||||
asc: sort[0] === '-' ? false : true,
|
||||
});
|
||||
});
|
||||
|
||||
return _.defaults({}, filter.context, {orderedBy : orderedBy});
|
||||
},
|
||||
get_groupby: function () { return [filter.context]; },
|
||||
get_domain: function () { return filter.domain; }
|
||||
},
|
||||
|
||||
@@ -3332,7 +3332,7 @@ var BasicModel = AbstractModel.extend({
|
||||
model: params.modelName,
|
||||
offset: params.offset || (type === 'record' ? _.indexOf(res_ids, res_id) : 0),
|
||||
openGroupByDefault: params.openGroupByDefault,
|
||||
orderedBy: params.orderedBy || [],
|
||||
orderedBy: params.orderedBy || (params.context && params.context.orderedBy) || [],
|
||||
orderedResIDs: params.orderedResIDs,
|
||||
parentID: params.parentID,
|
||||
rawContext: params.rawContext,
|
||||
@@ -4016,6 +4016,7 @@ var BasicModel = AbstractModel.extend({
|
||||
|
||||
if (options.context !== undefined) {
|
||||
element.context = options.context;
|
||||
element.orderedBy = options.context.orderedBy || element.orderedBy;
|
||||
}
|
||||
if (options.domain !== undefined) {
|
||||
element.domain = options.domain;
|
||||
|
||||
@@ -78,6 +78,14 @@ var ListController = BasicController.extend({
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
},
|
||||
/*
|
||||
* @override
|
||||
*/
|
||||
getContext: function () {
|
||||
var context = this._super.apply(this, arguments);
|
||||
context.orderedBy = this.model.get(this.handle, {raw: true}).orderedBy || [];
|
||||
return context;
|
||||
},
|
||||
/**
|
||||
* Returns the list of currently selected res_ids (with the check boxes on
|
||||
* the left)
|
||||
@@ -179,6 +187,7 @@ var ListController = BasicController.extend({
|
||||
} else {
|
||||
this.selectedRecords = [];
|
||||
}
|
||||
|
||||
params.selectedRecords = this.selectedRecords;
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
@@ -307,6 +307,99 @@ QUnit.module('Views', {
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('ordered list, sort attribute in context', function (assert) {
|
||||
assert.expect(1);
|
||||
// Equivalent to saving a custom filter
|
||||
|
||||
this.data.foo.fields.foo.sortable = true;
|
||||
this.data.foo.fields.date.sortable = true;
|
||||
|
||||
var list = createView({
|
||||
View: ListView,
|
||||
model: 'foo',
|
||||
data: this.data,
|
||||
arch: '<tree>' +
|
||||
'<field name="foo"/>' +
|
||||
'<field name="date"/>' +
|
||||
'</tree>',
|
||||
});
|
||||
|
||||
// Descending order on Foo
|
||||
list.$('th.o_column_sortable:contains("Foo")').click();
|
||||
list.$('th.o_column_sortable:contains("Foo")').click();
|
||||
|
||||
// Ascending order on Date
|
||||
list.$('th.o_column_sortable:contains("Date")').click();
|
||||
|
||||
var listContext = list.getContext();
|
||||
assert.deepEqual(listContext,
|
||||
{
|
||||
orderedBy: [{
|
||||
name: 'date',
|
||||
asc: true,
|
||||
}, {
|
||||
name: 'foo',
|
||||
asc: false,
|
||||
}]
|
||||
}, 'the list should have the right orderedBy in context');
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('Loading a filter with a sort attribute', function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
this.data.foo.fields.foo.sortable = true;
|
||||
this.data.foo.fields.date.sortable = true;
|
||||
|
||||
var searchReads = 0;
|
||||
var list = createView({
|
||||
View: ListView,
|
||||
model: 'foo',
|
||||
data: this.data,
|
||||
arch: '<tree>' +
|
||||
'<field name="foo"/>' +
|
||||
'<field name="date"/>' +
|
||||
'</tree>',
|
||||
context: {
|
||||
orderedBy: [{
|
||||
name: 'date',
|
||||
asc: true,
|
||||
}, {
|
||||
name: 'foo',
|
||||
asc: false,
|
||||
}]
|
||||
},
|
||||
mockRPC: function (route, args) {
|
||||
if (route === '/web/dataset/search_read') {
|
||||
if (searchReads === 0) {
|
||||
assert.strictEqual(args.sort, 'date ASC, foo DESC',
|
||||
'The sort attribute of the filter should be used by the initial search_read');
|
||||
} else if (searchReads === 1) {
|
||||
assert.strictEqual(args.sort, 'date DESC, foo ASC',
|
||||
'The sort attribute of the filter should be used by the next search_read');
|
||||
}
|
||||
searchReads += 1;
|
||||
}
|
||||
return this._super.apply(this,arguments);
|
||||
},
|
||||
});
|
||||
|
||||
// Simulate loading a filter
|
||||
list.update({
|
||||
context: {
|
||||
orderedBy: [{
|
||||
name: 'date',
|
||||
asc: false,
|
||||
}, {
|
||||
name: 'foo',
|
||||
asc: true,
|
||||
}]
|
||||
}
|
||||
});
|
||||
|
||||
list.destroy()
|
||||
});
|
||||
|
||||
QUnit.test('many2one field rendering', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user