[FIX] web: fix widget wrapper and weekdays widget
Before this commit, `WidgetWrapper` tried to redirect the call to `updateState` on its wrapped component but it can happen that the wrapper is not mounted yet and thus calling a function on its wrapped component will crash. This commit changes the implementation of `WidgetWrapper.updateState` to redirect the call to `this.update` which will update the props of the wrapped component and not directly its state. task 2504521 closes odoo/odoo#69421 X-original-commit: 67f09b9a9df248fec26f53758e76070ab3171435 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
@@ -9,10 +9,15 @@ odoo.define('web.WidgetWrapper', function (require) {
|
||||
// Public
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* This function should be used to update the "widget" Component's props,
|
||||
* not its state!
|
||||
*
|
||||
* @param {any} state
|
||||
* @returns Promise
|
||||
*/
|
||||
updateState(state) {
|
||||
if (this.componentRef.comp.updateState) {
|
||||
this.componentRef.comp.updateState(state);
|
||||
}
|
||||
return this.update(Object.assign({}, this.props, { record: state }));
|
||||
}
|
||||
}
|
||||
return WidgetWrapper;
|
||||
|
||||
@@ -19,9 +19,12 @@ odoo.define('web.WeekDays', function (require) {
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} nextProps
|
||||
* @param {Object} nextProps.record
|
||||
*/
|
||||
updateState(state) {
|
||||
this.state.days = this._prepareData(state.data);
|
||||
async willUpdateProps(nextProps) {
|
||||
this.state.days = this._prepareData(nextProps.record.data);
|
||||
this.mode = nextProps.options.mode;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
odoo.define('web.OwlCompatibilityTests', function (require) {
|
||||
"use strict";
|
||||
|
||||
const AbstractField = require('web.AbstractField');
|
||||
const fieldRegistry = require('web.field_registry');
|
||||
const widgetRegistry = require('web.widgetRegistry');
|
||||
const FormView = require('web.FormView');
|
||||
|
||||
const { ComponentAdapter, ComponentWrapper, WidgetAdapterMixin } = require('web.OwlCompatibility');
|
||||
const testUtils = require('web.test_utils');
|
||||
const Widget = require('web.Widget');
|
||||
@@ -1301,5 +1306,64 @@ odoo.define('web.OwlCompatibilityTests', function (require) {
|
||||
|
||||
parent.destroy();
|
||||
});
|
||||
|
||||
QUnit.module("WidgetWrapper");
|
||||
|
||||
QUnit.test("correctly update widget component during mounting", async function (assert) {
|
||||
// It comes with a fix for a bug that occurred because in some circonstances,
|
||||
// a widget component can be updated twice.
|
||||
// Specifically, this occurs when there is 'pad' widget in the form view, because this
|
||||
// widget does a 'setValue' in its 'renderEdit', which thus resets the widget component.
|
||||
assert.expect(4);
|
||||
|
||||
const PadLikeWidget = fieldRegistry.get('char').extend({
|
||||
_renderEdit() {
|
||||
assert.step("setValue");
|
||||
this._setValue("some value");
|
||||
}
|
||||
});
|
||||
fieldRegistry.add('pad_like', PadLikeWidget);
|
||||
|
||||
class WidgetComponent extends Component {}
|
||||
WidgetComponent.template = xml`<div>Widget</div>`;
|
||||
widgetRegistry.add("widget_comp", WidgetComponent);
|
||||
|
||||
const form = await testUtils.createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
res_id: 1,
|
||||
data: {
|
||||
partner: {
|
||||
fields: {
|
||||
id: {string: "id", type:"integer"},
|
||||
foo: {string: "Foo", type: "char"},
|
||||
},
|
||||
records: [{
|
||||
id: 1,
|
||||
foo: "value",
|
||||
}],
|
||||
},
|
||||
},
|
||||
arch: `
|
||||
<form><sheet><group>
|
||||
<field name="foo" widget="pad_like" />
|
||||
<widget name="widget_comp" />
|
||||
</group></sheet></form>
|
||||
`,
|
||||
});
|
||||
|
||||
assert.containsOnce(form, ".o_form_view.o_form_readonly");
|
||||
|
||||
await testUtils.dom.click(form.$(".o_form_label")[0]);
|
||||
await testUtils.nextTick(); // wait for quick edit
|
||||
|
||||
assert.containsOnce(form, ".o_form_view.o_form_editable");
|
||||
assert.verifySteps(["setValue"]);
|
||||
|
||||
form.destroy();
|
||||
|
||||
delete fieldRegistry.map.pad_like;
|
||||
delete widgetRegistry.map.widget_comp;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user