[IMP] web, web_editor: translation dialog for new translate api
This commit is contained in:
@@ -944,25 +944,15 @@ var BasicController = AbstractController.extend(FieldManagerMixin, {
|
||||
}
|
||||
var record = this.model.get(ev.data.id, { raw: true });
|
||||
var res_id = record.res_id || record.res_ids[0];
|
||||
var result = await this._rpc({
|
||||
route: '/web/dataset/call_button',
|
||||
params: {
|
||||
model: 'ir.translation',
|
||||
method: 'translate_fields',
|
||||
args: [record.model, res_id, ev.data.fieldName],
|
||||
kwargs: { context: record.getContext() },
|
||||
}
|
||||
});
|
||||
|
||||
this.translationDialog = new TranslationDialog(this, {
|
||||
domain: result.domain,
|
||||
searchName: result.context.search_default_name,
|
||||
fieldName: ev.data.fieldName,
|
||||
resId: res_id,
|
||||
userLanguageValue: ev.target.value || '',
|
||||
dataPointModel: record.model,
|
||||
dataPointID: record.id,
|
||||
isComingFromTranslationAlert: ev.data.isComingFromTranslationAlert,
|
||||
isText: result.context.translation_type === 'text',
|
||||
showSrc: result.context.translation_show_src,
|
||||
context: record.getContext(),
|
||||
});
|
||||
return this.translationDialog.open();
|
||||
},
|
||||
|
||||
@@ -14,29 +14,24 @@ odoo.define('web.TranslationDialog', function (require) {
|
||||
* @constructor
|
||||
* @param {Widget} parent
|
||||
* @param {Object} [options]
|
||||
* @param {string} [options.domain] the domain needed to get the translation terms
|
||||
* @param {string} [options.fieldName] the name of the field currently translated (from the model of the form view)
|
||||
* @param {string} [options.searchName] the name of the actual field that is the reference for translation (in the form of model,field)
|
||||
* @param {integer} [options.resId] the ID of record currently translated
|
||||
* @param {string} [options.userLanguageValue] the value of the translation in the language of the user, as seen in the from view (might be empty)
|
||||
* @param {string} [options.dataPointID] the data point id of the record for which we do the translations
|
||||
* @param {boolean} [options.isComingFromTranslationAlert] the initiator of the dialog, might be a link on a field or the translation alert on top of the form
|
||||
* @param {boolean} [options.isText] is the field a text field (multiline) or char (single line)
|
||||
* @param {boolean} [options.showSrc] is the source of the translation should be rendered (for partial translations, i.e. XML content)
|
||||
*
|
||||
*/
|
||||
init: function (parent, options) {
|
||||
options = options || {};
|
||||
|
||||
this.fieldName = options.fieldName;
|
||||
this.domain = options.domain;
|
||||
this.searchName = options.searchName;
|
||||
this.resId = options.resId;
|
||||
this.userLanguageValue = options.userLanguageValue;
|
||||
this.domain.push(['name', "=", `${this.searchName}`]);
|
||||
this.dataPointModel = options.dataPointModel;
|
||||
this.dataPointID = options.dataPointID;
|
||||
this.isComingFromTranslationAlert = options.isComingFromTranslationAlert;
|
||||
this.currentInterfaceLanguage = session.user_context.lang;
|
||||
this.isText = options.isText;
|
||||
this.showSrc = options.showSrc;
|
||||
this.context = options.context;
|
||||
|
||||
this._super(parent, _.extend({
|
||||
size: 'large',
|
||||
@@ -56,31 +51,35 @@ odoo.define('web.TranslationDialog', function (require) {
|
||||
this._loadLanguages().then((l) => {
|
||||
this.languages = l;
|
||||
return this._loadTranslations().then((t) => {
|
||||
this.translations = t;
|
||||
[this.translations, this.context] = t;
|
||||
let id = 1;
|
||||
this.translations.forEach((t) => t['id'] = id++);
|
||||
this.isText = this.context.translation_type === 'text';
|
||||
this.showSource = this.context.translation_show_source;
|
||||
});
|
||||
}),
|
||||
]).then(() => {
|
||||
this.data = this.translations.map((term) => {
|
||||
let relatedLanguage = this.languages.find((language) => language[0] === term.lang);
|
||||
if (!term.value && !this.showSrc) {
|
||||
term.value = term.src;
|
||||
if (!term.value && !this.showSource) {
|
||||
term.value = term.source;
|
||||
}
|
||||
return {
|
||||
id: term.id,
|
||||
lang: term.lang,
|
||||
langName: relatedLanguage[1],
|
||||
source: term.src,
|
||||
source: term.source,
|
||||
// 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
|
||||
value: (term.lang === this.currentInterfaceLanguage &&
|
||||
!this.showSrc &&
|
||||
!this.showSource &&
|
||||
!this.isComingFromTranslationAlert) ?
|
||||
this.userLanguageValue : term.value || ''
|
||||
};
|
||||
});
|
||||
this.data.sort((left, right) =>
|
||||
(left.langName < right.langName || (left.langName === right.langName && left.source < right.source)) ? -1 : 1);
|
||||
left.langName.localeCompare(right.langName));
|
||||
});
|
||||
},
|
||||
|
||||
@@ -92,12 +91,11 @@ odoo.define('web.TranslationDialog', function (require) {
|
||||
* @private
|
||||
*/
|
||||
_loadTranslations: function () {
|
||||
const domain = [...this.domain, ['lang', 'in', this.languages.map(l => l[0])]];
|
||||
return this._rpc({
|
||||
model: 'ir.translation',
|
||||
method: 'search_read',
|
||||
fields: ['lang', 'src', 'value'],
|
||||
domain: domain,
|
||||
model: this.dataPointModel,
|
||||
method: 'get_field_translations',
|
||||
args: [[this.resId], this.fieldName],
|
||||
context: this.context,
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -137,16 +135,16 @@ odoo.define('web.TranslationDialog', function (require) {
|
||||
this.el.querySelectorAll('input[type=text],textarea').forEach((t) => {
|
||||
var initialValue = this.data.find((d) => d.id == t.dataset.id);
|
||||
if (initialValue.value !== t.value) {
|
||||
updatedTerm[t.dataset.id] = t.value;
|
||||
updatedTerm[t.dataset.id] = {lang: initialValue.lang, source: initialValue.source, value: t.value};
|
||||
|
||||
if (initialValue.lang === this.currentInterfaceLanguage && !this.showSrc) {
|
||||
if (initialValue.lang === this.currentInterfaceLanguage && !this.showSource) {
|
||||
// when the user has changed the term for the language he is
|
||||
// using in the interface, this change should be reflected
|
||||
// in the form view
|
||||
// partial translations being handled server side are
|
||||
// also ignored
|
||||
var changes = {};
|
||||
changes[this.fieldName] = updatedTerm[initialValue.id];
|
||||
changes[this.fieldName] = t.value;
|
||||
updateFormViewField = {
|
||||
dataPointID: this.dataPointID,
|
||||
changes: changes,
|
||||
@@ -158,16 +156,23 @@ odoo.define('web.TranslationDialog', function (require) {
|
||||
|
||||
// updatedTerm only contains the id and values of the terms that
|
||||
// have been updated by the user
|
||||
var saveUpdatedTermsProms = Object.keys(updatedTerm).map((id) => {
|
||||
var writeTranslation = {
|
||||
model: 'ir.translation',
|
||||
method: 'write',
|
||||
context: this.context,
|
||||
args: [[parseInt(id, 10)], { value: updatedTerm[id] }]
|
||||
};
|
||||
return this._rpc(writeTranslation);
|
||||
});
|
||||
return Promise.all(saveUpdatedTermsProms).then(() => {
|
||||
const translations = {};
|
||||
if (this.showSource) { // model terms translation
|
||||
Object.entries(updatedTerm).forEach(([id, term]) => {
|
||||
if (!translations[term.lang]) {
|
||||
translations[term.lang] = {};
|
||||
}
|
||||
translations[term.lang][term.source] = term.value;
|
||||
});
|
||||
}
|
||||
else { // model translation
|
||||
Object.entries(updatedTerm).forEach(([id, term]) => translations[term.lang] = term.value);
|
||||
}
|
||||
return this._rpc({
|
||||
model: this.dataPointModel,
|
||||
method: 'update_field_translations',
|
||||
args: [[this.resId], this.fieldName, translations],
|
||||
}).then(() => {
|
||||
// we might have to update the value of the field on the form
|
||||
// view that opened the translation dialog
|
||||
if (updateFormViewField) {
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
<templates id="template" xml:space="preserve">
|
||||
<div t-name="web.TranslationDialogWidget" class="o_translation_dialog">
|
||||
<div class="row" t-foreach="widget.data" t-as="term">
|
||||
<div t-attf-class="col-12 #{widget.showSrc ? 'col-lg-2' : 'col-lg-3'} #{widget.currentInterfaceLanguage == term.lang ? 'o_language_current' : ''}">
|
||||
<div t-attf-class="col-12 #{widget.showSource ? 'col-lg-2' : 'col-lg-3'} #{widget.currentInterfaceLanguage == term.lang ? 'o_language_current' : ''}">
|
||||
<t t-esc="term.langName"></t>
|
||||
</div>
|
||||
<div t-if="widget.showSrc" class="col-12 col-lg-3 source">
|
||||
<div t-if="widget.showSource" class="col-12 col-lg-3 source">
|
||||
<t t-esc="term.source"></t>
|
||||
</div>
|
||||
<div t-attf-class="col-12 #{widget.showSrc ? 'col-lg-7' : 'col-lg-9'} translation">
|
||||
<div t-attf-class="col-12 #{widget.showSource ? 'col-lg-7' : 'col-lg-9'} translation">
|
||||
<input t-if="!widget.isText" type="text"
|
||||
class="o_field_char o_input"
|
||||
t-att-value="term.value"
|
||||
@@ -17,7 +17,7 @@
|
||||
<textarea t-if="widget.isText"
|
||||
t-esc="term.value"
|
||||
t-att-data-id="term.id"
|
||||
t-att-rows="widget.showSrc ? 2 : 5"
|
||||
t-att-rows="widget.showSource ? 2 : 5"
|
||||
class="o_field_text o_field_translate o_field_widget o_input">
|
||||
</textarea>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,6 @@ const { Component, useEnv } = owl;
|
||||
*/
|
||||
export function useTranslationDialog() {
|
||||
const dialog = useService("dialog");
|
||||
const rpc = useService("rpc");
|
||||
const env = useEnv();
|
||||
|
||||
async function openTranslationDialog({ record, fieldName, updateField }) {
|
||||
@@ -43,22 +42,14 @@ export function useTranslationDialog() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const { resModel, resId, context } = record;
|
||||
const result = await rpc("/web/dataset/call_button", {
|
||||
model: "ir.translation",
|
||||
method: "translate_fields",
|
||||
args: [resModel, resId, fieldName],
|
||||
kwargs: { context },
|
||||
});
|
||||
const { resModel, resId } = record;
|
||||
|
||||
dialog.add(TranslationDialog, {
|
||||
domain: result.domain,
|
||||
searchName: result.context.search_default_name,
|
||||
fieldName: fieldName,
|
||||
resId: resId,
|
||||
resModel: resModel,
|
||||
userLanguageValue: record.data[fieldName] || "",
|
||||
isComingFromTranslationAlert: false,
|
||||
isText: result.context.translation_type === "text",
|
||||
showSource: result.context.translation_show_src,
|
||||
updateField,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,18 +20,22 @@ export class TranslationDialog extends Component {
|
||||
|
||||
onWillStart(async () => {
|
||||
const languages = await loadLanguages(this.orm);
|
||||
const translations = await this.loadTranslations(languages);
|
||||
const [translations, context] = await this.loadTranslations(languages);
|
||||
let id = 1;
|
||||
translations.forEach((t) => (t.id = id++));
|
||||
this.props.isText = context.translation_type === "text";
|
||||
this.props.showSource = context.translation_show_source;
|
||||
|
||||
this.terms = translations.map((term) => {
|
||||
const relatedLanguage = languages.find((l) => l[0] === term.lang);
|
||||
if (!term.value && !this.props.showSource) {
|
||||
term.value = term.src;
|
||||
term.value = term.source;
|
||||
}
|
||||
return {
|
||||
id: term.id,
|
||||
lang: term.lang,
|
||||
langName: relatedLanguage[1],
|
||||
source: term.src,
|
||||
source: term.source,
|
||||
// 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
|
||||
@@ -43,11 +47,7 @@ export class TranslationDialog extends Component {
|
||||
: term.value || "",
|
||||
};
|
||||
});
|
||||
this.terms.sort((a, b) =>
|
||||
a.langName < b.langName || (a.langName === b.langName && a.source < b.source)
|
||||
? -1
|
||||
: 1
|
||||
);
|
||||
this.terms.sort((a, b) => a.langName.localeCompare(b.langName));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -63,23 +63,37 @@ export class TranslationDialog extends Component {
|
||||
* Load the translation terms for the installed language, for the current model and res_id
|
||||
*/
|
||||
async loadTranslations(languages) {
|
||||
const domain = [...this.domain, ["lang", "in", languages.map((l) => l[0])]];
|
||||
return this.orm.searchRead("ir.translation", domain, ["lang", "src", "value"]);
|
||||
return this.orm.call(this.props.resModel, "get_field_translations", [
|
||||
[this.props.resId],
|
||||
this.props.fieldName,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all the terms that have been updated
|
||||
*/
|
||||
async onSave() {
|
||||
await Promise.all(
|
||||
this.terms.map(async (term) => {
|
||||
if (term.id in this.updatedTerms && term.value !== this.updatedTerms[term.id]) {
|
||||
await this.orm.write("ir.translation", [term.id], {
|
||||
value: this.updatedTerms[term.id],
|
||||
});
|
||||
const translations = {};
|
||||
|
||||
this.terms.map((term) => {
|
||||
const updatedTermValue = this.updatedTerms[term.id];
|
||||
if (term.id in this.updatedTerms && term.value !== updatedTermValue) {
|
||||
if (this.props.showSource) {
|
||||
if (!translations[term.lang]) {
|
||||
translations[term.lang] = {};
|
||||
}
|
||||
translations[term.lang][term.source] = updatedTermValue;
|
||||
} else {
|
||||
translations[term.lang] = updatedTermValue;
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
await this.orm.call(this.props.resModel, "update_field_translations", [
|
||||
[this.props.resId],
|
||||
this.props.fieldName,
|
||||
translations,
|
||||
]);
|
||||
|
||||
// we might have to update the value of the field on the form
|
||||
// view that opened the translation dialog
|
||||
|
||||
@@ -160,19 +160,6 @@ QUnit.module('Legacy basic_fields', {
|
||||
position: "after",
|
||||
}]
|
||||
},
|
||||
"ir.translation": {
|
||||
fields: {
|
||||
lang: {type: "char"},
|
||||
value: {type: "char"},
|
||||
res_id: {type: "integer"}
|
||||
},
|
||||
records: [{
|
||||
id: 99,
|
||||
res_id: 37,
|
||||
value: '',
|
||||
lang: 'en_US'
|
||||
}]
|
||||
},
|
||||
};
|
||||
|
||||
target = getFixture();
|
||||
@@ -1653,25 +1640,18 @@ QUnit.module('Legacy basic_fields', {
|
||||
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: 'partnes,foo'},
|
||||
});
|
||||
if (route === "/web/dataset/call_kw/partner/get_field_translations") {
|
||||
assert.deepEqual(args.args, [[1],"foo"], "should translate the foo field of the record");
|
||||
return Promise.resolve([
|
||||
[{lang: "en_US", source: "yop", value: "yop"}, {lang: "fr_BE", source: "yop", value: "valeur français"}],
|
||||
{translation_type: "char", translation_show_source: false},
|
||||
]);
|
||||
}
|
||||
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: '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");
|
||||
if (route === "/web/dataset/call_kw/partner/update_field_translations") {
|
||||
assert.deepEqual(args.args, [[1], "foo", {"en_US": "english value"}], "the new translation value should be written");
|
||||
return Promise.resolve();
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
@@ -1741,31 +1721,21 @@ QUnit.module('Legacy basic_fields', {
|
||||
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/partner/get_field_translations") {
|
||||
assert.deepEqual(args.args, [[1],"foo"], "should translate the foo field of the record");
|
||||
return Promise.resolve([
|
||||
[{lang: "en_US", source: "first paragraph", value: "first paragraph"},
|
||||
{lang: "en_US", source: "second paragraph", value: "second paragraph"},
|
||||
{lang: "fr_BE", source: "first paragraph", value: "premier paragraphe"},
|
||||
{lang: "fr_BE", source: "second paragraph", value: "deuxième paragraphe"}],
|
||||
{translation_type: "char", translation_show_source: 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");
|
||||
if (route === "/web/dataset/call_kw/partner/update_field_translations") {
|
||||
assert.deepEqual(args.args, [[1], "foo", {"en_US": {"first paragraph": "first paragraph modified"}}], "the new translation value should be written");
|
||||
return Promise.resolve();
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
@@ -2694,15 +2664,15 @@ QUnit.module('Legacy basic_fields', {
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
mockRPC: function (route, args) {
|
||||
if (route === "/web/dataset/call_button" && args.method === 'translate_fields') {
|
||||
assert.deepEqual(args.args, ["partner",1,"txt"], 'should call "call_button" route');
|
||||
return Promise.resolve({
|
||||
domain: [],
|
||||
context: {search_default_name: 'partnes,foo'},
|
||||
});
|
||||
if (route === "/web/dataset/call_kw/partner/get_field_translations") {
|
||||
assert.deepEqual(args.args, [[1],"txt"], "should translate the txt field of the record");
|
||||
return Promise.resolve([
|
||||
[{lang: "en_US", source: "yop", value: "yop"}, {lang: "fr_BE", source: "yop", value: "valeur français"}],
|
||||
{translation_type: "text", translation_show_source: false},
|
||||
]);
|
||||
}
|
||||
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)"]]);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
@@ -140,19 +140,6 @@ QUnit.module('LegacyViews', {
|
||||
{id: 14, display_name: "silver", color: 5},
|
||||
]
|
||||
},
|
||||
"ir.translation": {
|
||||
fields: {
|
||||
lang_code: {type: "char"},
|
||||
value: {type: "char"},
|
||||
res_id: {type: "integer"}
|
||||
},
|
||||
records: [{
|
||||
id: 99,
|
||||
res_id: 12,
|
||||
value: '',
|
||||
lang_code: 'en_US'
|
||||
}]
|
||||
},
|
||||
user: {
|
||||
fields: {
|
||||
name: {string: "Name", type: "char"},
|
||||
@@ -7382,16 +7369,7 @@ QUnit.module('LegacyViews', {
|
||||
});
|
||||
|
||||
QUnit.test('translation alerts preserved on reverse breadcrumb', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
serverData.models['ir.translation'] = {
|
||||
fields: {
|
||||
name: { string: "name", type: "char" },
|
||||
source: {string: "Source", type: "char"},
|
||||
value: {string: "Value", type: "char"},
|
||||
},
|
||||
records: [],
|
||||
};
|
||||
assert.expect(1);
|
||||
|
||||
serverData.models.partner.fields.foo.translate = true;
|
||||
|
||||
@@ -7402,12 +7380,6 @@ QUnit.module('LegacyViews', {
|
||||
'</sheet>' +
|
||||
'</form>',
|
||||
'partner,false,search': '<search></search>',
|
||||
'ir.translation,false,list': '<tree>' +
|
||||
'<field name="name"/>' +
|
||||
'<field name="source"/>' +
|
||||
'<field name="value"/>' +
|
||||
'</tree>',
|
||||
'ir.translation,false,search': '<search></search>',
|
||||
};
|
||||
|
||||
serverData.actions = {
|
||||
@@ -7418,14 +7390,6 @@ QUnit.module('LegacyViews', {
|
||||
type: 'ir.actions.act_window',
|
||||
views: [[false, 'form']],
|
||||
},
|
||||
2: {
|
||||
id: 2,
|
||||
name: 'Translate',
|
||||
res_model: 'ir.translation',
|
||||
type: 'ir.actions.act_window',
|
||||
views: [[false, 'list']],
|
||||
target: 'current',
|
||||
}
|
||||
};
|
||||
|
||||
const webClient = await createWebClient({ serverData });
|
||||
@@ -7440,13 +7404,6 @@ QUnit.module('LegacyViews', {
|
||||
|
||||
assert.containsOnce(target, '.o_legacy_form_view .alert > div',
|
||||
"should have a translation alert");
|
||||
|
||||
await doAction(webClient, 2);
|
||||
|
||||
await testUtils.dom.click($('.o_control_panel .breadcrumb a:first'));
|
||||
await legacyExtraNextTick();
|
||||
assert.containsOnce(target, '.o_legacy_form_view .alert > div',
|
||||
"should have a translation alert");
|
||||
});
|
||||
|
||||
QUnit.test('translate event correctly handled with multiple controllers', async function (assert) {
|
||||
@@ -7485,16 +7442,16 @@ QUnit.module('LegacyViews', {
|
||||
if (route === '/web/dataset/call_kw/product/get_formview_id') {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
if (route === "/web/dataset/call_button" && args.method === 'translate_fields') {
|
||||
assert.deepEqual(args.args, ["product",37,"name"], 'should call "call_button" route');
|
||||
if (route === "/web/dataset/call_kw/product/get_field_translations") {
|
||||
assert.deepEqual(args.args, [[37],"name"], "should translate the name field of the record");
|
||||
nbTranslateCalls++;
|
||||
return Promise.resolve({
|
||||
domain: [],
|
||||
context: {search_default_name: 'partnes,foo'},
|
||||
});
|
||||
return Promise.resolve([
|
||||
[{lang: "en_US", source: "yop", value: "yop"}, {lang: "fr_BE", source: "yop", value: "valeur français"}],
|
||||
{translation_type: "char", translation_show_source: false},
|
||||
]);
|
||||
}
|
||||
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)"]]);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
@@ -123,31 +123,6 @@ QUnit.module('LegacyViews', {
|
||||
{id: "2-20170808020000", name: "virtual"},
|
||||
]
|
||||
},
|
||||
"ir.translation": {
|
||||
fields: {
|
||||
lang_code: {type: "char"},
|
||||
src: {type: "char"},
|
||||
value: {type: "char"},
|
||||
res_id: {type: "integer"},
|
||||
name: {type: "char"},
|
||||
lang: {type: "char"},
|
||||
},
|
||||
records: [{
|
||||
id: 99,
|
||||
res_id: 1,
|
||||
value: '',
|
||||
lang_code: 'en_US',
|
||||
lang: 'en_US',
|
||||
name: 'foo,foo'
|
||||
},{
|
||||
id: 100,
|
||||
res_id: 1,
|
||||
value: '',
|
||||
lang_code: 'fr_BE',
|
||||
lang: 'fr_BE',
|
||||
name: 'foo,foo'
|
||||
}]
|
||||
},
|
||||
};
|
||||
|
||||
serverData = { models: this.data };
|
||||
@@ -3620,11 +3595,11 @@ QUnit.module('LegacyViews', {
|
||||
model: 'foo',
|
||||
data: this.data,
|
||||
mockRPC: function (route, args) {
|
||||
if (route === "/web/dataset/call_button" && args.method === 'translate_fields') {
|
||||
return Promise.resolve({
|
||||
domain: [],
|
||||
context: {search_default_name: 'foo,foo'},
|
||||
});
|
||||
if (route === "/web/dataset/call_kw/foo/get_field_translations") {
|
||||
return Promise.resolve([
|
||||
[{lang: "en_US", source: "yop", value: "yop"}, {lang: "fr_BE", source: "yop", value: "valeur français"}],
|
||||
{translation_type: "char", translation_show_source: false},
|
||||
]);
|
||||
}
|
||||
if (route === "/web/dataset/call_kw/res.lang/get_installed") {
|
||||
return Promise.resolve([["en_US","English"], ["fr_BE", "Frenglish"]]);
|
||||
|
||||
@@ -123,21 +123,6 @@ QUnit.module("Fields", (hooks) => {
|
||||
},
|
||||
],
|
||||
},
|
||||
"ir.translation": {
|
||||
fields: {
|
||||
lang: { type: "char" },
|
||||
value: { type: "char" },
|
||||
res_id: { type: "integer" },
|
||||
},
|
||||
records: [
|
||||
{
|
||||
id: 99,
|
||||
res_id: 37,
|
||||
value: "",
|
||||
lang: "en_US",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -301,7 +286,7 @@ QUnit.module("Fields", (hooks) => {
|
||||
});
|
||||
|
||||
QUnit.test("char field translatable", async function (assert) {
|
||||
assert.expect(13);
|
||||
assert.expect(11);
|
||||
|
||||
serverData.models.partner.fields.foo.translate = true;
|
||||
serviceRegistry.add("localization", makeFakeLocalizationService({ multiLang: true }), {
|
||||
@@ -325,33 +310,25 @@ QUnit.module("Fields", (hooks) => {
|
||||
</sheet>
|
||||
</form>`,
|
||||
mockRPC(route, { args, method, model }) {
|
||||
if (route === "/web/dataset/call_button" && method === "translate_fields") {
|
||||
assert.deepEqual(
|
||||
args,
|
||||
["partner", 1, "foo"],
|
||||
'should call "call_button" route'
|
||||
);
|
||||
return Promise.resolve({
|
||||
domain: [],
|
||||
context: { search_default_name: "partnes,foo" },
|
||||
});
|
||||
}
|
||||
if (route === "/web/dataset/call_kw/res.lang/get_installed") {
|
||||
return Promise.resolve([
|
||||
["en_US", "English"],
|
||||
["fr_BE", "French (Belgium)"],
|
||||
]);
|
||||
}
|
||||
if (method === "search_read" && model === "ir.translation") {
|
||||
if (route === "/web/dataset/call_kw/partner/get_field_translations") {
|
||||
return Promise.resolve([
|
||||
{ lang: "en_US", src: "yop", value: "yop", id: 42 },
|
||||
{ lang: "fr_BE", src: "yop", value: "valeur français", id: 43 },
|
||||
[
|
||||
{ lang: "en_US", source: "yop", value: "yop" },
|
||||
{ lang: "fr_BE", source: "yop", value: "valeur français" },
|
||||
],
|
||||
{ translation_type: "char", translation_show_source: false },
|
||||
]);
|
||||
}
|
||||
if (method === "write" && model === "ir.translation") {
|
||||
if (route === "/web/dataset/call_kw/partner/update_field_translations") {
|
||||
assert.deepEqual(
|
||||
args[1],
|
||||
{ value: "english value" },
|
||||
args[2],
|
||||
{ en_US: "english value" },
|
||||
"the new translation value should be written"
|
||||
);
|
||||
return Promise.resolve(null);
|
||||
@@ -417,7 +394,7 @@ QUnit.module("Fields", (hooks) => {
|
||||
});
|
||||
|
||||
QUnit.test("html field translatable", async function (assert) {
|
||||
assert.expect(6);
|
||||
assert.expect(5);
|
||||
|
||||
serverData.models.partner.fields.foo.translate = true;
|
||||
serviceRegistry.add("localization", makeFakeLocalizationService({ multiLang: true }), {
|
||||
@@ -441,55 +418,48 @@ QUnit.module("Fields", (hooks) => {
|
||||
</sheet>
|
||||
</form>`,
|
||||
mockRPC(route, { args, method, model }) {
|
||||
if (route === "/web/dataset/call_button" && method === "translate_fields") {
|
||||
assert.deepEqual(
|
||||
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 (method === "search_read" && model === "ir.translation") {
|
||||
if (route === "/web/dataset/call_kw/partner/get_field_translations") {
|
||||
return Promise.resolve([
|
||||
{ lang: "en_US", src: "first paragraph", value: "first paragraph", id: 42 },
|
||||
[
|
||||
{
|
||||
lang: "en_US",
|
||||
source: "first paragraph",
|
||||
value: "first paragraph",
|
||||
},
|
||||
{
|
||||
lang: "en_US",
|
||||
source: "second paragraph",
|
||||
value: "second paragraph",
|
||||
},
|
||||
{
|
||||
lang: "fr_BE",
|
||||
source: "first paragraph",
|
||||
value: "premier paragraphe",
|
||||
},
|
||||
{
|
||||
lang: "fr_BE",
|
||||
source: "second paragraph",
|
||||
value: "deuxième paragraphe",
|
||||
},
|
||||
],
|
||||
{
|
||||
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,
|
||||
translation_type: "char",
|
||||
translation_show_source: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
if (method === "write" && model === "ir.translation") {
|
||||
|
||||
if (route === "/web/dataset/call_kw/partner/update_field_translations") {
|
||||
assert.deepEqual(
|
||||
args[1],
|
||||
{ value: "first paragraph modified" },
|
||||
"Wrong update on translation"
|
||||
args[2],
|
||||
{ en_US: { "first paragraph": "first paragraph modified" } },
|
||||
"the new translation value should be written"
|
||||
);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
@@ -49,21 +49,6 @@ QUnit.module("Fields", (hooks) => {
|
||||
},
|
||||
],
|
||||
},
|
||||
"ir.translation": {
|
||||
fields: {
|
||||
lang: { type: "char" },
|
||||
value: { type: "char" },
|
||||
res_id: { type: "integer" },
|
||||
},
|
||||
records: [
|
||||
{
|
||||
id: 99,
|
||||
res_id: 37,
|
||||
value: "",
|
||||
lang: "en_US",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -370,7 +355,7 @@ QUnit.module("Fields", (hooks) => {
|
||||
});
|
||||
|
||||
QUnit.test("text field translatable", async function (assert) {
|
||||
assert.expect(4);
|
||||
assert.expect(3);
|
||||
|
||||
serverData.models.partner.fields.txt.translate = true;
|
||||
serviceRegistry.add("localization", makeFakeLocalizationService({ multiLang: true }), {
|
||||
@@ -391,19 +376,20 @@ QUnit.module("Fields", (hooks) => {
|
||||
</sheet>
|
||||
</form>`,
|
||||
mockRPC(route, { args, method }) {
|
||||
if (route === "/web/dataset/call_button" && method === "translate_fields") {
|
||||
assert.deepEqual(
|
||||
args,
|
||||
["partner", 1, "txt"],
|
||||
`should call "call_button" route`
|
||||
);
|
||||
return Promise.resolve({
|
||||
domain: [],
|
||||
context: { search_default_name: "partnes,foo" },
|
||||
});
|
||||
}
|
||||
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 (route === "/web/dataset/call_kw/partner/get_field_translations") {
|
||||
return Promise.resolve([
|
||||
[
|
||||
{ lang: "en_US", source: "yop", value: "yop" },
|
||||
{ lang: "fr_BE", source: "yop", value: "valeur français" },
|
||||
],
|
||||
{ translation_type: "text", translation_show_source: false },
|
||||
]);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -180,21 +180,6 @@ QUnit.module("Views", (hooks) => {
|
||||
{ id: 14, display_name: "silver", color: 5 },
|
||||
],
|
||||
},
|
||||
"ir.translation": {
|
||||
fields: {
|
||||
lang_code: { type: "char" },
|
||||
value: { type: "char" },
|
||||
res_id: { type: "integer" },
|
||||
},
|
||||
records: [
|
||||
{
|
||||
id: 99,
|
||||
res_id: 12,
|
||||
value: "",
|
||||
lang_code: "en_US",
|
||||
},
|
||||
],
|
||||
},
|
||||
user: {
|
||||
fields: {
|
||||
name: { string: "Name", type: "char" },
|
||||
@@ -8466,20 +8451,16 @@ QUnit.module("Views", (hooks) => {
|
||||
["CUST2", "second custom"],
|
||||
];
|
||||
}
|
||||
if (args.method === "translate_fields") {
|
||||
if (route === "/web/dataset/call_kw/partner/get_field_translations") {
|
||||
assert.step(`translate args ${JSON.stringify(args.args)}`);
|
||||
assert.step(`translate context ${JSON.stringify(args.kwargs.context)}`);
|
||||
return {
|
||||
domain: [["res_id", "=", args.args[1]]],
|
||||
context: { search_default_name: "partner_type,foo" },
|
||||
};
|
||||
}
|
||||
if (args.method === "search_read" && args.model === "ir.translation") {
|
||||
assert.step(
|
||||
`search_read translations args: ${JSON.stringify(
|
||||
args.args
|
||||
)} ; kwargs: ${JSON.stringify(args.kwargs)}`
|
||||
);
|
||||
return Promise.resolve([
|
||||
[
|
||||
{ lang: "CUST", source: "yop", value: "yop" },
|
||||
{ lang: "CUST2", source: "yop", value: "valeur français" },
|
||||
],
|
||||
{ translation_type: "char", translation_show_source: false },
|
||||
]);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -8487,9 +8468,8 @@ QUnit.module("Views", (hooks) => {
|
||||
|
||||
await click(target, ".o_field_translate.btn-link");
|
||||
assert.verifySteps([
|
||||
`translate args ["partner",1,"foo"]`,
|
||||
`translate args [[1],"foo"]`,
|
||||
`translate context {"lang":"en","uid":7,"tz":"taht"}`,
|
||||
`search_read translations args: [] ; kwargs: {"domain":[["res_id","=",1],["name","=","partner_type,foo"],["lang","in",["CUST","CUST2"]]],"fields":["lang","src","value"],"context":{"lang":"en","uid":7,"tz":"taht"}}`,
|
||||
]);
|
||||
|
||||
assert.containsOnce(target, ".modal");
|
||||
@@ -8522,6 +8502,15 @@ QUnit.module("Views", (hooks) => {
|
||||
["CUST2", "second custom"],
|
||||
];
|
||||
}
|
||||
if (route === "/web/dataset/call_kw/partner/get_field_translations") {
|
||||
return Promise.resolve([
|
||||
[
|
||||
{ lang: "CUST", source: "yop", value: "yop" },
|
||||
{ lang: "CUST2", source: "yop", value: "valeur français" },
|
||||
],
|
||||
{ translation_type: "char", translation_show_source: false },
|
||||
]);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -8536,7 +8525,7 @@ QUnit.module("Views", (hooks) => {
|
||||
|
||||
await click(target, ".o_field_translate.btn-link");
|
||||
await click(target.querySelectorAll(".modal-footer button")[0]); // save
|
||||
assert.verifySteps(["create", "read", "translate_fields", "get_installed", "search_read"]);
|
||||
assert.verifySteps(["create", "read", "get_installed", "get_field_translations"]);
|
||||
assert.containsOnce(target, ".modal");
|
||||
assert.strictEqual(target.querySelector(".modal-title").textContent, "Translate: foo");
|
||||
});
|
||||
@@ -8583,12 +8572,21 @@ QUnit.module("Views", (hooks) => {
|
||||
["CUST2", "second custom"],
|
||||
];
|
||||
}
|
||||
if (route === "/web/dataset/call_kw/partner/get_field_translations") {
|
||||
return Promise.resolve([
|
||||
[
|
||||
{ lang: "CUST", source: "yop", value: "yop" },
|
||||
{ lang: "CUST2", source: "yop", value: "valeur français" },
|
||||
],
|
||||
{ translation_type: "char", translation_show_source: false },
|
||||
]);
|
||||
}
|
||||
},
|
||||
});
|
||||
assert.verifySteps(["get_views", "read"]);
|
||||
await clickEdit(target);
|
||||
await click(target, ".o_field_legacy_char .o_field_translate.btn-link");
|
||||
assert.verifySteps(["translate_fields", "get_installed", "search_read"]);
|
||||
assert.verifySteps(["get_installed", "get_field_translations"]);
|
||||
assert.containsOnce(target, ".modal");
|
||||
assert.strictEqual(target.querySelector(".modal-title").textContent, "Translate: foo");
|
||||
});
|
||||
@@ -8644,22 +8642,11 @@ QUnit.module("Views", (hooks) => {
|
||||
});
|
||||
|
||||
QUnit.test("translation alerts preserved on reverse breadcrumb", async function (assert) {
|
||||
serverData.models["ir.translation"] = {
|
||||
fields: {
|
||||
name: { string: "name", type: "char" },
|
||||
source: { string: "Source", type: "char" },
|
||||
value: { string: "Value", type: "char" },
|
||||
},
|
||||
records: [],
|
||||
};
|
||||
|
||||
serverData.models.partner.fields.foo.translate = true;
|
||||
|
||||
serverData.views = {
|
||||
"partner,false,form": `<form><sheet><field name="foo"/></sheet></form>`,
|
||||
"partner,false,search": "<search></search>",
|
||||
"ir.translation,false,list": `<tree><field name="name"/><field name="source"/><field name="value"/></tree>`,
|
||||
"ir.translation,false,search": "<search></search>",
|
||||
};
|
||||
|
||||
serverData.actions = {
|
||||
@@ -8670,15 +8657,6 @@ QUnit.module("Views", (hooks) => {
|
||||
type: "ir.actions.act_window",
|
||||
views: [[false, "form"]],
|
||||
},
|
||||
2: {
|
||||
id: 2,
|
||||
name: "Translate",
|
||||
res_model: "ir.translation",
|
||||
type: "ir.actions.act_window",
|
||||
views: [[false, "list"]],
|
||||
target: "current",
|
||||
flags: { search_view: true, action_buttons: true },
|
||||
},
|
||||
};
|
||||
|
||||
const webClient = await createWebClient({ serverData });
|
||||
@@ -8692,17 +8670,12 @@ QUnit.module("Views", (hooks) => {
|
||||
await clickSave(target);
|
||||
|
||||
assert.containsOnce(target, ".alert .o_field_translate", "should have a translation alert");
|
||||
|
||||
await doAction(webClient, 2);
|
||||
|
||||
await click(target.querySelector(".o_control_panel .breadcrumb a:nth-child(1)"));
|
||||
assert.containsOnce(target, ".alert .o_field_translate", "should have a translation alert");
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"translate event correctly handled with multiple controllers",
|
||||
async function (assert) {
|
||||
assert.expect(3);
|
||||
assert.expect(2);
|
||||
|
||||
serverData.models.product.fields.name.translate = true;
|
||||
serverData.models.partner.records[0].product_id = 37;
|
||||
@@ -8742,23 +8715,21 @@ QUnit.module("Views", (hooks) => {
|
||||
if (route === "/web/dataset/call_kw/product/get_formview_id") {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
route === "/web/dataset/call_button" &&
|
||||
args.method === "translate_fields"
|
||||
) {
|
||||
assert.deepEqual(
|
||||
args.args,
|
||||
["product", 37, "name"],
|
||||
'should call "call_button" route'
|
||||
);
|
||||
nbTranslateCalls++;
|
||||
return {
|
||||
domain: [],
|
||||
context: { search_default_name: "partnes,foo" },
|
||||
};
|
||||
}
|
||||
if (route === "/web/dataset/call_kw/res.lang/get_installed") {
|
||||
return [["en_US"], ["fr_BE"]];
|
||||
return [
|
||||
["en_US", "English"],
|
||||
["fr_BE", "French (Belgium)"],
|
||||
];
|
||||
}
|
||||
if (route === "/web/dataset/call_kw/product/get_field_translations") {
|
||||
nbTranslateCalls++;
|
||||
return Promise.resolve([
|
||||
[
|
||||
{ lang: "en_US", source: "yop", value: "yop" },
|
||||
{ lang: "fr_BE", source: "yop", value: "valeur français" },
|
||||
],
|
||||
{ translation_type: "char", translation_show_source: false },
|
||||
]);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -197,34 +197,6 @@ QUnit.module("Views", (hooks) => {
|
||||
},
|
||||
records: [{ id: "2-20170808020000", name: "virtual" }],
|
||||
},
|
||||
"ir.translation": {
|
||||
fields: {
|
||||
lang_code: { type: "char" },
|
||||
src: { type: "char" },
|
||||
value: { type: "char" },
|
||||
res_id: { type: "integer" },
|
||||
name: { type: "char" },
|
||||
lang: { type: "char" },
|
||||
},
|
||||
records: [
|
||||
{
|
||||
id: 99,
|
||||
res_id: 1,
|
||||
value: "",
|
||||
lang_code: "en_US",
|
||||
lang: "en_US",
|
||||
name: "foo,foo",
|
||||
},
|
||||
{
|
||||
id: 100,
|
||||
res_id: 1,
|
||||
value: "",
|
||||
lang_code: "fr_BE",
|
||||
lang: "fr_BE",
|
||||
name: "foo,foo",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
setupViewRegistries();
|
||||
@@ -4096,18 +4068,21 @@ QUnit.module("Views", (hooks) => {
|
||||
resModel: "foo",
|
||||
serverData,
|
||||
mockRPC(route, args) {
|
||||
if (route === "/web/dataset/call_button" && args.method === "translate_fields") {
|
||||
return Promise.resolve({
|
||||
domain: [],
|
||||
context: { search_default_name: "foo,foo" },
|
||||
});
|
||||
}
|
||||
if (route === "/web/dataset/call_kw/res.lang/get_installed") {
|
||||
return Promise.resolve([
|
||||
["en_US", "English"],
|
||||
["fr_BE", "Frenglish"],
|
||||
]);
|
||||
}
|
||||
if (route === "/web/dataset/call_kw/foo/get_field_translations") {
|
||||
return Promise.resolve([
|
||||
[
|
||||
{ lang: "en_US", source: "yop", value: "yop" },
|
||||
{ lang: "fr_BE", source: "yop", value: "valeur français" },
|
||||
],
|
||||
{ translation_type: "char", translation_show_source: false },
|
||||
]);
|
||||
}
|
||||
},
|
||||
arch: '<tree editable="top">' + '<field name="foo" required="1"/>' + "</tree>",
|
||||
});
|
||||
|
||||
@@ -130,19 +130,6 @@ QUnit.module('web_editor', {}, function () {
|
||||
body_arch: "<div class='field_body'>yep</div>",
|
||||
}],
|
||||
},
|
||||
"ir.translation": {
|
||||
fields: {
|
||||
lang_code: {type: "char"},
|
||||
value: {type: "char"},
|
||||
res_id: {type: "integer"}
|
||||
},
|
||||
records: [{
|
||||
id: 99,
|
||||
res_id: 12,
|
||||
value: '',
|
||||
lang_code: 'en_US'
|
||||
}]
|
||||
},
|
||||
});
|
||||
|
||||
testUtils.mock.patch(ajax, {
|
||||
@@ -880,15 +867,18 @@ QUnit.module('web_editor', {}, function () {
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
mockRPC: function (route, args) {
|
||||
if (route === '/web/dataset/call_button' && args.method === 'translate_fields') {
|
||||
assert.deepEqual(args.args, ['note.note', 1, 'body'], "should call 'call_button' route");
|
||||
return Promise.resolve({
|
||||
domain: [],
|
||||
context: {search_default_name: 'partnes,foo'},
|
||||
});
|
||||
if (route === "/web/dataset/call_kw/note.note/get_field_translations") {
|
||||
assert.deepEqual(args.args, [[1],"body"], "should translate the body field of the record");
|
||||
return Promise.resolve([
|
||||
[{lang: "en_US", source: "first paragraph", value: "first paragraph"},
|
||||
{lang: "en_US", source: "second paragraph", value: "second paragraph"},
|
||||
{lang: "fr_BE", source: "first paragraph", value: "premier paragraphe"},
|
||||
{lang: "fr_BE", source: "second paragraph", value: "deuxième paragraphe"}],
|
||||
{translation_type: "text", translation_show_source: true},
|
||||
]);
|
||||
}
|
||||
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)"]]);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user