[FIX] web: read context when reloading Graph or Pivot views
Before this rev., keys like pivot_measures, graph_mode..., were correctly took into account at first load of Pivot or Graph view, but not at reload. Those keys are particularily useful when a user saves a research to its favorites. When such a favorite is selected, the view is reloaded and the interesting information is in the context.
This commit is contained in:
@@ -101,11 +101,21 @@ var GraphController = AbstractController.extend({
|
||||
self._updateButtons();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_update: function () {
|
||||
this._updateButtons();
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
/**
|
||||
* makes sure that the buttons in the control panel matches the current
|
||||
* state (so, correct active buttons and stuff like that)
|
||||
*/
|
||||
_updateButtons: function () {
|
||||
if (!this.$buttons) {
|
||||
return;
|
||||
}
|
||||
var state = this.model.get();
|
||||
this.$buttons.find('.o_graph_button').removeClass('active');
|
||||
this.$buttons
|
||||
|
||||
@@ -55,14 +55,15 @@ return AbstractModel.extend({
|
||||
* to keep track of various entities.
|
||||
*/
|
||||
load: function (params) {
|
||||
this.initialGroupBys = params.groupBys;
|
||||
var groupBys = params.context.graph_groupbys || params.groupBys;
|
||||
this.initialGroupBys = groupBys;
|
||||
this.fields = params.fields;
|
||||
this.modelName = params.modelName;
|
||||
this.chart = {
|
||||
data: [],
|
||||
groupedBy: params.groupedBy.length ? params.groupedBy : params.groupBys,
|
||||
measure: params.measure,
|
||||
mode: params.mode,
|
||||
groupedBy: params.groupedBy.length ? params.groupedBy : groupBys,
|
||||
measure: params.context.graph_measure || params.measure,
|
||||
mode: params.context.graph_mode || params.mode,
|
||||
domain: params.domain,
|
||||
context: params.context,
|
||||
};
|
||||
@@ -85,6 +86,12 @@ return AbstractModel.extend({
|
||||
* @returns {Deferred}
|
||||
*/
|
||||
reload: function (handle, params) {
|
||||
if ('context' in params) {
|
||||
this.chart.context = params.context;
|
||||
this.chart.groupedBy = params.context.graph_groupbys || this.chart.groupedBy;
|
||||
this.chart.measure = params.context.graph_measure || this.chart.measure;
|
||||
this.chart.mode = params.context.graph_mode || this.chart.mode;
|
||||
}
|
||||
if ('domain' in params) {
|
||||
this.chart.domain = params.domain;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ var GraphView = AbstractView.extend({
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init: function (viewInfo, params) {
|
||||
init: function (viewInfo) {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
var measure;
|
||||
@@ -57,9 +57,9 @@ var GraphView = AbstractView.extend({
|
||||
this.controllerParams.measures = measures;
|
||||
this.rendererParams.stacked = viewInfo.arch.attrs.stacked !== "False";
|
||||
|
||||
this.loadParams.mode = params.context.graph_mode || viewInfo.arch.attrs.type || 'bar';
|
||||
this.loadParams.measure = params.context.graph_measure || measure || '__count__';
|
||||
this.loadParams.groupBys = params.context.graph_groupbys || groupBys || [];
|
||||
this.loadParams.mode = viewInfo.arch.attrs.type || 'bar';
|
||||
this.loadParams.measure = measure || '__count__';
|
||||
this.loadParams.groupBys = groupBys || [];
|
||||
this.loadParams.fields = viewInfo.fields;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -222,27 +222,16 @@ var PivotModel = AbstractModel.extend({
|
||||
* @returns {Deferred}
|
||||
*/
|
||||
load: function (params) {
|
||||
// In the preview implementation of the pivot view (a.k.a. version 2),
|
||||
// the virtual field used to display the number of records was named
|
||||
// __count__, whereas __count is actually the one used in xml. So
|
||||
// basically, activating a filter specifying __count as measures crashed.
|
||||
// Unfortunately, as __count__ was used in the JS, all filters saved as
|
||||
// favorite at that time were saved with __count__, and not __count.
|
||||
// So in order the make them still work with the new implementation, we
|
||||
// simply rename __count__ into __count at this unique entry point.
|
||||
var measures = _.map(params.measures, function (measure) {
|
||||
return measure === '__count__' ? '__count' : measure;
|
||||
});
|
||||
this.initialDomain = params.domain;
|
||||
this.initialRowGroupBys = params.rowGroupBys;
|
||||
this.initialRowGroupBys = params.context.pivot_row_groupby || params.rowGroupBys;
|
||||
this.fields = params.fields;
|
||||
this.modelName = params.modelName;
|
||||
this.data = {
|
||||
domain: params.domain,
|
||||
context: _.extend({}, session.user_context, params.context),
|
||||
groupedBy: params.groupedBy,
|
||||
colGroupBys: params.colGroupBys,
|
||||
measures: measures,
|
||||
colGroupBys: params.context.pivot_column_groupby || params.colGroupBys,
|
||||
measures: this._processMeasures(params.context.pivot_measures) || params.measures,
|
||||
sorted_column: {},
|
||||
};
|
||||
this.defaultGroupedBy = params.groupedBy;
|
||||
@@ -256,6 +245,12 @@ var PivotModel = AbstractModel.extend({
|
||||
*/
|
||||
reload: function (handle, params) {
|
||||
var self = this;
|
||||
if ('context' in params) {
|
||||
this.data.context = params.context;
|
||||
this.data.colGroupBys = params.context.pivot_column_groupby || this.data.colGroupBys;
|
||||
this.data.groupedBy = params.context.pivot_row_groupby || this.data.groupedBy;
|
||||
this.data.measures = this._processMeasures(params.context.pivot_measures) || this.data.measures;
|
||||
}
|
||||
if ('domain' in params) {
|
||||
this.data.domain = params.domain;
|
||||
} else {
|
||||
@@ -272,7 +267,7 @@ var PivotModel = AbstractModel.extend({
|
||||
var old_col_root = this.data.main_col.root;
|
||||
return this._loadData().then(function () {
|
||||
var new_groupby_length;
|
||||
if (!('groupBy' in params)) {
|
||||
if (!('groupBy' in params) && !('pivot_row_groupby' in (params.context || {}))) {
|
||||
// we only update the row groupbys according to the old groupbys
|
||||
// if we don't have the key 'groupBy' in params. In that case,
|
||||
// we want to have the full open state for the groupbys.
|
||||
@@ -659,6 +654,29 @@ var PivotModel = AbstractModel.extend({
|
||||
this.data.main_row.root = main_row_header;
|
||||
this.data.main_col.root = main_col_header;
|
||||
},
|
||||
/**
|
||||
* In the preview implementation of the pivot view (a.k.a. version 2),
|
||||
* the virtual field used to display the number of records was named
|
||||
* __count__, whereas __count is actually the one used in xml. So
|
||||
* basically, activating a filter specifying __count as measures crashed.
|
||||
* Unfortunately, as __count__ was used in the JS, all filters saved as
|
||||
* favorite at that time were saved with __count__, and not __count.
|
||||
* So in order the make them still work with the new implementation, we
|
||||
* handle both __count__ and __count.
|
||||
*
|
||||
* This function replaces in the given array of measures occurences of
|
||||
* '__count__' by '__count'.
|
||||
*
|
||||
* @param {Array[string] || undefined} measures
|
||||
* @return {Array[string] || undefined}
|
||||
*/
|
||||
_processMeasures: function (measures) {
|
||||
if (measures) {
|
||||
return _.map(measures, function (measure) {
|
||||
return measure === '__count__' ? '__count' : measure;
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Format a value to a usable string, for the renderer to display.
|
||||
*
|
||||
|
||||
@@ -87,9 +87,9 @@ var PivotView = AbstractView.extend({
|
||||
activeMeasures.push('__count');
|
||||
}
|
||||
|
||||
this.loadParams.measures = params.context.pivot_measures || activeMeasures;
|
||||
this.loadParams.colGroupBys = params.context.pivot_column_groupby || colGroupBys;
|
||||
this.loadParams.rowGroupBys = params.context.pivot_row_groupby || rowGroupBys;
|
||||
this.loadParams.measures = activeMeasures;
|
||||
this.loadParams.colGroupBys = colGroupBys;
|
||||
this.loadParams.rowGroupBys = rowGroupBys;
|
||||
this.loadParams.fields = fields;
|
||||
|
||||
this.controllerParams.title = params.title || arch.attrs.string || _t("Untitled");
|
||||
|
||||
@@ -372,6 +372,52 @@ QUnit.module('Views', {
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('correctly uses graph_ keys from the context (at reload)', function (assert) {
|
||||
var done = assert.async();
|
||||
assert.expect(8);
|
||||
|
||||
var graph = createView({
|
||||
View: GraphView,
|
||||
model: "foo",
|
||||
data: this.data,
|
||||
arch: '<graph><field name="product_id"/></graph>',
|
||||
});
|
||||
|
||||
assert.strictEqual(graph.renderer.state.mode, "bar", "should be in bar chart mode");
|
||||
assert.ok(graph.$buttons.find('button[data-mode="bar"]').hasClass('active'),
|
||||
'bar chart button should be active');
|
||||
|
||||
var reloadParams = {
|
||||
context: {
|
||||
graph_measure: 'foo',
|
||||
graph_mode: 'line',
|
||||
graph_groupbys: ['color_id'],
|
||||
},
|
||||
};
|
||||
graph.reload(reloadParams);
|
||||
return concurrency.delay(0).then(function () {
|
||||
// check measure
|
||||
assert.strictEqual(graph.$('text.nv-legend-text:contains(Foo)').length, 1,
|
||||
"should now use the 'foo' measure");
|
||||
|
||||
// check mode
|
||||
assert.strictEqual(graph.renderer.state.mode, "line", "should be in line chart mode");
|
||||
assert.notOk(graph.$buttons.find('button[data-mode="bar"]').hasClass('active'),
|
||||
'bar chart button should not be active');
|
||||
assert.ok(graph.$buttons.find('button[data-mode="line"]').hasClass('active'),
|
||||
'line chart button should be active');
|
||||
|
||||
// check groupbys
|
||||
assert.strictEqual(graph.$('text:contains(xphone)').length, 0,
|
||||
"should not contain a text element with product in legend");
|
||||
assert.strictEqual(graph.$('text:contains(red)').length, 1,
|
||||
"should contain a text element with color in legend");
|
||||
|
||||
graph.destroy();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('reload graph with correct fields', function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
|
||||
@@ -825,6 +825,53 @@ QUnit.module('Views', {
|
||||
pivot.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('correctly uses pivot_ keys from the context (at reload)', function (assert) {
|
||||
assert.expect(8);
|
||||
|
||||
this.data.partner.fields.amount = {string: "Amount", type: "float"};
|
||||
|
||||
var pivot = createView({
|
||||
View: PivotView,
|
||||
model: "partner",
|
||||
data: this.data,
|
||||
arch: '<pivot>' +
|
||||
'<field name="date" interval="day" type="col"/>' +
|
||||
'<field name="amount" type="measure"/>' +
|
||||
'</pivot>',
|
||||
});
|
||||
|
||||
assert.strictEqual(pivot.$('tbody tr:first td.o_pivot_cell_value:last').text(), '0.00',
|
||||
"the active measure should be amount");
|
||||
|
||||
var reloadParams = {
|
||||
context: {
|
||||
pivot_measures: ['foo'],
|
||||
pivot_column_groupby: ['customer'],
|
||||
pivot_row_groupby: ['product_id'],
|
||||
},
|
||||
};
|
||||
pivot.reload(reloadParams);
|
||||
|
||||
assert.strictEqual(pivot.$('thead .o_pivot_header_cell_opened').length, 1,
|
||||
"column: should have one opened header");
|
||||
assert.strictEqual(pivot.$('thead .o_pivot_header_cell_closed:contains(First)').length, 1,
|
||||
"column: should display one closed header with 'First'");
|
||||
assert.strictEqual(pivot.$('thead .o_pivot_header_cell_closed:contains(Second)').length, 1,
|
||||
"column: should display one closed header with 'Second'");
|
||||
|
||||
assert.strictEqual(pivot.$('tbody .o_pivot_header_cell_opened').length, 1,
|
||||
"row: should have one opened header");
|
||||
assert.strictEqual(pivot.$('tbody .o_pivot_header_cell_closed:contains(xphone)').length, 1,
|
||||
"row: should display one closed header with 'xphone'");
|
||||
assert.strictEqual(pivot.$('tbody .o_pivot_header_cell_closed:contains(xpad)').length, 1,
|
||||
"row: should display one closed header with 'xpad'");
|
||||
|
||||
assert.strictEqual(pivot.$('tbody tr:first td:nth(3)').text(), '32',
|
||||
"selected measure should be foo, with total 32");
|
||||
|
||||
pivot.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('correctly use group_by key from the context', function (assert) {
|
||||
assert.expect(7);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user