[FIX] web: get next config for model loaded with values
In `web_hierarchy`, the model is always loaded with values. However, when a record (component) props are updated, its resId can change (i.e. if the ordering in the hierarchy view changes), therefore not only the `root` of the model should be updated with the provided values, but the config should be reevaluated as well since some record (datapoint) getters use it. task-3562116 Part-of: odoo/odoo#143941
This commit is contained in:
@@ -12,10 +12,9 @@ class StandaloneRelationalModel extends RelationalModel {
|
||||
load(params = {}) {
|
||||
if (params.values) {
|
||||
const data = params.values;
|
||||
if (params.mode) {
|
||||
this.config.mode = params.mode;
|
||||
}
|
||||
this.root = this._createRoot(this.config, data);
|
||||
const config = this._getNextConfig(this.config, params);
|
||||
this.root = this._createRoot(config, data);
|
||||
this.config = config;
|
||||
return;
|
||||
}
|
||||
return super.load(params);
|
||||
@@ -50,7 +49,7 @@ class _Record extends Component {
|
||||
modelServices.orm = this.orm;
|
||||
this.model = useState(new StandaloneRelationalModel(this.env, modelParams, modelServices));
|
||||
|
||||
const loadWithValues = async (values) => {
|
||||
const prepareLoadWithValues = async (values) => {
|
||||
values = pick(values, ...Object.keys(modelParams.config.activeFields));
|
||||
const proms = [];
|
||||
for (const fieldName in values) {
|
||||
@@ -113,20 +112,26 @@ class _Record extends Component {
|
||||
}
|
||||
await Promise.all(proms);
|
||||
}
|
||||
return this.model.load({ values });
|
||||
return values;
|
||||
};
|
||||
onWillStart(() => {
|
||||
onWillStart(async () => {
|
||||
if (this.props.values) {
|
||||
return loadWithValues(this.props.values);
|
||||
const values = await prepareLoadWithValues(this.props.values);
|
||||
return this.model.load({ values });
|
||||
} else {
|
||||
return this.model.load();
|
||||
}
|
||||
});
|
||||
onWillUpdateProps((nextProps) => {
|
||||
onWillUpdateProps(async (nextProps) => {
|
||||
const params = {};
|
||||
if (nextProps.info.resId !== this.model.root.resId) {
|
||||
params.resId = nextProps.info.resId;
|
||||
}
|
||||
if (nextProps.values) {
|
||||
return loadWithValues(nextProps.values);
|
||||
} else if (nextProps.info.resId !== this.model.root.resId) {
|
||||
return this.model.load({ resId: nextProps.info.resId });
|
||||
params.values = await prepareLoadWithValues(nextProps.values);
|
||||
}
|
||||
if (Object.keys(params).length) {
|
||||
return this.model.load(params);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -607,4 +607,72 @@ QUnit.module("Record Component", (hooks) => {
|
||||
assert.strictEqual(increment.textContent, "2");
|
||||
assert.strictEqual(field.textContent, "blop");
|
||||
});
|
||||
|
||||
QUnit.test("can switch records with values", async (assert) => {
|
||||
class Parent extends Component {
|
||||
setup() {
|
||||
this.fields = {
|
||||
foo: {
|
||||
name: "foo",
|
||||
type: "char",
|
||||
},
|
||||
bar: {
|
||||
name: "bar",
|
||||
type: "boolean",
|
||||
},
|
||||
};
|
||||
this.values = {
|
||||
foo: "abc",
|
||||
bar: true,
|
||||
};
|
||||
this.state = useState({ currentId: 99 });
|
||||
}
|
||||
|
||||
next() {
|
||||
this.state.currentId = 100;
|
||||
this.values = {
|
||||
foo: "def",
|
||||
bar: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
Parent.components = { Record, Field };
|
||||
Parent.template = xml`
|
||||
<a id="next" t-on-click="next">NEXT</a>
|
||||
<Record resId="state.currentId" resModel="'partner'" fieldNames="['foo']" fields="fields" values="values" t-slot-scope="data">
|
||||
<Field name="'foo'" record="data.record"/>
|
||||
</Record>
|
||||
`;
|
||||
let _record;
|
||||
patchWithCleanup(Record.components._Record.prototype, {
|
||||
setup() {
|
||||
super.setup();
|
||||
_record = this;
|
||||
},
|
||||
});
|
||||
|
||||
await mount(Parent, target, {
|
||||
env: await makeTestEnv({
|
||||
serverData,
|
||||
mockRPC(route) {
|
||||
assert.step(route);
|
||||
},
|
||||
}),
|
||||
});
|
||||
// No load since the values are provided to the record
|
||||
assert.verifySteps([]);
|
||||
const field = target.querySelector("div[name='foo']");
|
||||
// First values are loaded
|
||||
assert.strictEqual(field.textContent, "abc");
|
||||
// Verify that the underlying _Record Model root has the specified resId
|
||||
assert.strictEqual(_record.model.root.resId, 99);
|
||||
|
||||
await click(target.querySelector("#next"));
|
||||
// Still no load.
|
||||
assert.verifySteps([]);
|
||||
// Second values are loaded
|
||||
assert.strictEqual(field.textContent, "def");
|
||||
// Verify that the underlying _Record Model root has the updated resId
|
||||
assert.strictEqual(_record.model.root.resId, 100);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user