[FIX] web: translate html fields

This commit fixes:
- body of a email.template in a small field
- translation of website_description of a product does not show the
  source of the translation
- translation of website_description of a product shows the full
  content for the current language

HTML fields are typically fields with longer of content.
If the field is an HTML field, it should be displayed in a textarea,
like the text fields.

Most of HTML fields are split in meaningful chunks of content (using
xml_translate or html_translate method).
For these fields, the source must be displayed.

Also sort the entries on the source to have a consistent order

closes odoo/odoo#37215

Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
This commit is contained in:
Martin Trigaux
2019-09-24 15:52:55 +00:00
parent 5a9cb64414
commit 2471ee506f
6 changed files with 150 additions and 9 deletions
@@ -1109,7 +1109,7 @@ QUnit.module('basic_fields', {
});
QUnit.test('char field translatable', async function (assert) {
assert.expect(4);
assert.expect(12);
this.data.partner.fields.foo.translate = true;
@@ -1128,6 +1128,9 @@ QUnit.module('basic_fields', {
'</sheet>' +
'</form>',
res_id: 1,
session: {
user_context: {lang: 'en_US'},
},
mockRPC: function (route, args) {
if (route === "/web/dataset/call_button" && args.method === 'translate_fields') {
assert.deepEqual(args.args, ["partner",1,"foo"], 'should call "call_button" route');
@@ -1137,7 +1140,18 @@ QUnit.module('basic_fields', {
});
}
if (route === "/web/dataset/call_kw/res.lang/get_installed") {
return Promise.resolve([["en_US"], ["fr_BE"]]);
return Promise.resolve([["en_US", "English"], ["fr_BE", "French (Belgium)"]]);
}
if (args.method === "search_read" && args.model == "ir.translation") {
return Promise.resolve([
{lang: 'en_US', src: 'yop', value: 'yop', id: 42},
{lang: 'fr_BE', src: 'yop', value: 'valeur français', id: 43}
]);
}
if (args.method === "write" && args.model == "ir.translation") {
assert.deepEqual(args.args[1], {value: "english value"},
"the new translation value should be written");
return Promise.resolve();
}
return this._super.apply(this, arguments);
},
@@ -1150,6 +1164,117 @@ QUnit.module('basic_fields', {
await testUtils.nextTick();
assert.containsOnce($(document), '.modal', 'a translate modal should be visible');
assert.containsN($('.modal .o_translation_dialog'), '.translation', 2,
'two rows should be visible');
var $enField = $('.modal .o_translation_dialog .translation:first() input');
assert.strictEqual($enField.val(), 'yop',
'English translation should be filled');
assert.strictEqual($('.modal .o_translation_dialog .translation:last() input').val(), 'valeur français',
'French translation should be filled');
await testUtils.fields.editInput($enField, "english value");
await testUtils.dom.click($('.modal button.btn-primary')); // save
await testUtils.nextTick();
var $foo = form.$('input[type="text"].o_field_char');
assert.strictEqual($foo.val(), "english value",
"the new translation was not transfered to modified record");
await testUtils.fields.editInput($foo, "new english value");
await testUtils.dom.click($button);
await testUtils.nextTick();
assert.strictEqual($('.modal .o_translation_dialog .translation:first() input').val(), 'new english value',
'Modified value should be used instead of translation');
assert.strictEqual($('.modal .o_translation_dialog .translation:last() input').val(), 'valeur français',
'French translation should be filled');
form.destroy();
_t.database.multi_lang = multiLang;
});
QUnit.test('html field translatable', async function (assert) {
assert.expect(6);
this.data.partner.fields.foo.translate = true;
var multiLang = _t.database.multi_lang;
_t.database.multi_lang = true;
var form = await createView({
View: FormView,
model: 'partner',
data: this.data,
arch: '<form string="Partners">' +
'<sheet>' +
'<group>' +
'<field name="foo"/>' +
'</group>' +
'</sheet>' +
'</form>',
res_id: 1,
session: {
user_context: {lang: 'en_US'},
},
mockRPC: function (route, args) {
if (route === "/web/dataset/call_button" && args.method === 'translate_fields') {
assert.deepEqual(args.args, ["partner",1,"foo"], 'should call "call_button" route');
return Promise.resolve({
domain: [],
context: {
search_default_name: 'partner,foo',
translation_type: 'char',
translation_show_src: true,
},
});
}
if (route === "/web/dataset/call_kw/res.lang/get_installed") {
return Promise.resolve([["en_US", "English"], ["fr_BE", "French (Belgium)"]]);
}
if (args.method === "search_read" && args.model == "ir.translation") {
return Promise.resolve([
{lang: 'en_US', src: 'first paragraph', value: 'first paragraph', id: 42},
{lang: 'en_US', src: 'second paragraph', value: 'second paragraph', id: 43},
{lang: 'fr_BE', src: 'first paragraph', value: 'premier paragraphe', id: 44},
{lang: 'fr_BE', src: 'second paragraph', value: 'deuxième paragraphe', id: 45},
]);
}
if (args.method === "write" && args.model == "ir.translation") {
assert.deepEqual(args.args[1], {value: "first paragraph modified"},
"Wrong update on translation");
return Promise.resolve();
}
return this._super.apply(this, arguments);
},
});
await testUtils.form.clickEdit(form);
var $foo = form.$('input[type="text"].o_field_char');
// this will not affect the translate_fields effect until the record is
// saved but is set for consistency of the test
await testUtils.fields.editInput($foo, "<p>first paragraph</p><p>second paragraph</p>");
var $button = form.$('input[type="text"].o_field_char + .o_field_translate');
await testUtils.dom.click($button);
await testUtils.nextTick();
assert.containsOnce($(document), '.modal', 'a translate modal should be visible');
assert.containsN($('.modal .o_translation_dialog'), '.translation', 4,
'four rows should be visible');
var $enField = $('.modal .o_translation_dialog .translation:first() input');
assert.strictEqual($enField.val(), 'first paragraph',
'first part of english translation should be filled');
await testUtils.fields.editInput($enField, "first paragraph modified");
await testUtils.dom.click($('.modal button.btn-primary')); // save
await testUtils.nextTick();
assert.strictEqual($foo.val(), "<p>first paragraph</p><p>second paragraph</p>",
"the new partial translation should not be transfered");
form.destroy();