[FIX] web: reload data when translation changes

before this commit:
model translation:
when the user changes the translation for the current language in the
translation dialog, the value in the form view is also updated and marked
modified.
But if the user wants to invalidate the translation and set the translation to
`false`, the form view value is also updated to `false`, if the user saves by
accident, all translations are lost.

model_terms translation:
when translations are modified in the translation dialog, the field value will
not be changed

after this commit:
form view data will be reloaded after translations changed in the translation
dialog

closes odoo/odoo#111869

X-original-commit: 9aab8347a1a4cc74050dd2e5035cba838b93863c
Signed-off-by: Wang Chong (cwg) <cwg@odoo.com>
This commit is contained in:
Chong Wang (cwg)
2023-02-03 16:32:34 +01:00
parent 4e282f10fc
commit 43b00d6b1a
6 changed files with 37 additions and 42 deletions
@@ -20,7 +20,6 @@
<TranslationButton
fieldName="props.name"
record="props.record"
updateField="props.update"
/>
</t>
</t>
@@ -20,7 +20,6 @@
<TranslationButton
fieldName="props.name"
record="props.record"
updateField="props.update"
/>
</t>
</div>
@@ -19,7 +19,7 @@ export function useTranslationDialog() {
const addDialog = useOwnedDialogs();
const env = useEnv();
async function openTranslationDialog({ record, fieldName, updateField }) {
async function openTranslationDialog({ record, fieldName }) {
if (!record.resId) {
let _continue = true;
await new Promise((resolve) => {
@@ -50,7 +50,10 @@ export function useTranslationDialog() {
resModel: resModel,
userLanguageValue: record.data[fieldName] || "",
isComingFromTranslationAlert: false,
updateField,
onSave: async () => {
await record.load({}, { keepChanges: true });
record.model.notify();
},
});
}
@@ -71,13 +74,12 @@ export class TranslationButton extends Component {
}
onClick() {
const { fieldName, record, updateField } = this.props;
this.translationDialog({ fieldName, record, updateField });
const { fieldName, record } = this.props;
this.translationDialog({ fieldName, record });
}
}
TranslationButton.template = "web.TranslationButton";
TranslationButton.props = {
fieldName: { type: String },
record: { type: Object },
updateField: { type: Function },
};
@@ -28,16 +28,23 @@ export class TranslationDialog extends Component {
this.terms = translations.map((term) => {
const relatedLanguage = languages.find((l) => l[0] === term.lang);
return {
const termInfo = {
...term,
langName: relatedLanguage[1],
value:
term.lang === this.user.lang &&
!this.props.showSource &&
!this.props.isComingFromTranslationAlert
? this.props.userLanguageValue
: term.value || "",
value: term.value || "",
};
// we set the translation value coming from the database, except for the language
// the user is currently utilizing. Then we set the translation value coming
// from the value of the field in the form
if (
term.lang === this.user.lang &&
!this.props.showSource &&
!this.props.isComingFromTranslationAlert
) {
this.updatedTerms[term.id] = this.props.userLanguageValue;
termInfo.value = this.props.userLanguageValue;
}
return termInfo;
});
this.terms.sort((a, b) => a.langName.localeCompare(b.langName));
});
@@ -88,19 +95,7 @@ export class TranslationDialog extends Component {
translations,
]);
// we might have to update the value of the field on the form
// view that opened the translation dialog
const currentTerm = this.terms.find(
(term) => term.lang === this.user.lang && !this.props.showSource
);
if (
currentTerm &&
currentTerm.id in this.updatedTerms &&
currentTerm.value !== this.updatedTerms[currentTerm.id]
) {
this.props.updateField(this.updatedTerms[currentTerm.id]);
}
await this.props.onSave();
this.props.close();
}
}
@@ -310,7 +310,7 @@ QUnit.module("Fields", (hooks) => {
return Promise.resolve([
[
{ lang: "en_US", source: "yop", value: "yop" },
{ lang: "fr_BE", source: "yop", value: "valeur français" },
{ lang: "fr_BE", source: "yop", value: "yop français" },
{ lang: "es_ES", source: "yop", value: "yop español" },
],
{ translation_type: "char", translation_show_source: false },
@@ -319,9 +319,9 @@ QUnit.module("Fields", (hooks) => {
if (call_get_field_translations === 1) {
return Promise.resolve([
[
{ lang: "en_US", source: "english value", value: "english value" },
{ lang: "fr_BE", source: "english value", value: "valeur français" },
{ lang: "es_ES", source: "english value", value: "english value" },
{ lang: "en_US", source: "bar", value: "bar" },
{ lang: "fr_BE", source: "bar", value: "yop français" },
{ lang: "es_ES", source: "bar", value: "bar" },
],
{ translation_type: "char", translation_show_source: false },
]);
@@ -330,9 +330,10 @@ QUnit.module("Fields", (hooks) => {
if (route === "/web/dataset/call_kw/partner/update_field_translations") {
assert.deepEqual(
args[2],
{ en_US: "english value", es_ES: false },
{ en_US: "bar", es_ES: false },
"the new translation value should be written and the value false voids the translation"
);
serverData.models.partner.records[0].foo = "bar";
return Promise.resolve(null);
}
},
@@ -366,7 +367,7 @@ QUnit.module("Fields", (hooks) => {
assert.strictEqual(translations[0].value, "yop", "English translation should be filled");
assert.strictEqual(
translations[1].value,
"valeur français",
"yop français",
"French translation should be filled"
);
assert.strictEqual(
@@ -375,33 +376,33 @@ QUnit.module("Fields", (hooks) => {
"Spanish translation should be filled"
);
await editInput(translations[0], null, "english value");
await editInput(translations[2], null, "");
await editInput(translations[0], null, "bar"); // set the en_US(user language) translation to "foo"
await editInput(translations[2], null, ""); // void the es_ES translation
await click(target, ".modal button.btn-primary"); // save
assert.strictEqual(
target.querySelector(`.o_field_char input[type="text"]`).value,
"english value",
"bar",
"the new translation was not transfered to modified record"
);
await editInput(target, `.o_field_char input[type="text"]`, "new english value");
await editInput(target, `.o_field_char input[type="text"]`, "baz");
await click(target, ".o_field_char .btn.o_field_translate");
translations = target.querySelectorAll(".modal .o_translation_dialog .translation input");
assert.strictEqual(
translations[0].value,
"new english value",
"baz",
"Modified value should be used instead of translation"
);
assert.strictEqual(
translations[1].value,
"valeur français",
"French translation should be filled"
"yop français",
"French translation shouldn't be changed"
);
assert.strictEqual(
translations[2].value,
"english value",
"bar",
"Spanish translation should fallback to the English translation"
);
});
@@ -30,7 +30,6 @@
<TranslationButton
fieldName="props.name"
record="props.record"
updateField="props.update"
/>
</span>
</t>