mirror of
https://github.com/OCA/web.git
synced 2025-02-22 13:21:25 +02:00
[IMP]web_translate_dialog: black, isort, prettier
This commit is contained in:
1
setup/web_translate_dialog/odoo/addons/web_translate_dialog
Symbolic link
1
setup/web_translate_dialog/odoo/addons/web_translate_dialog
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../../web_translate_dialog
|
||||
6
setup/web_translate_dialog/setup.py
Normal file
6
setup/web_translate_dialog/setup.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['setuptools-odoo'],
|
||||
odoo_addon=True,
|
||||
)
|
||||
@@ -5,23 +5,14 @@
|
||||
{
|
||||
"name": "Web Translate Dialog",
|
||||
"summary": "Easy-to-use pop-up to translate fields in several languages",
|
||||
"version": "12.0.1.1.3",
|
||||
"version": "13.0.1.0.0",
|
||||
"category": "Web",
|
||||
"website": "https://github.com/OCA/web",
|
||||
"author": "Camptocamp, "
|
||||
"Tecnativa, "
|
||||
"Odoo Community Association (OCA)",
|
||||
"author": "Camptocamp, " "Tecnativa, " "Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"application": False,
|
||||
'installable': True,
|
||||
"depends": [
|
||||
"web",
|
||||
],
|
||||
"data": [
|
||||
"views/res_lang.xml",
|
||||
"views/web_translate.xml",
|
||||
],
|
||||
"qweb": [
|
||||
"static/src/xml/base.xml",
|
||||
]
|
||||
"installable": True,
|
||||
"depends": ["web"],
|
||||
"data": ["views/res_lang.xml", "views/web_translate.xml"],
|
||||
"qweb": ["static/src/xml/base.xml"],
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Copyright 2019 Camptocamp SA
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
from odoo import models, api
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class BaseModel(models.BaseModel):
|
||||
|
||||
_inherit = 'base'
|
||||
_inherit = "base"
|
||||
|
||||
@api.multi
|
||||
def get_field_translations(self, field_names):
|
||||
@@ -15,22 +15,24 @@ class BaseModel(models.BaseModel):
|
||||
:return: dict of
|
||||
{self.id: {'lang_code': {'field_name':ir.translation,value}}
|
||||
"""
|
||||
read_res = self.with_context(lang='en_US').read(fields=field_names)
|
||||
read_res = self.with_context(lang="en_US").read(fields=field_names)
|
||||
res = {}
|
||||
for rec in read_res:
|
||||
rec_id = rec.get('id')
|
||||
del rec['id']
|
||||
res[rec_id] = {'en_US': rec}
|
||||
rec_id = rec.get("id")
|
||||
del rec["id"]
|
||||
res[rec_id] = {"en_US": rec}
|
||||
for rec_id, values in res.items():
|
||||
for name in field_names:
|
||||
|
||||
tr_read_res = self.env['ir.translation'].search_read([
|
||||
('name', '=', '%s,%s' % (self._name, name)),
|
||||
('res_id', '=', rec_id),
|
||||
('lang', '!=', 'en_US')
|
||||
])
|
||||
tr_read_res = self.env["ir.translation"].search_read(
|
||||
[
|
||||
("name", "=", "{},{}".format(self._name, name)),
|
||||
("res_id", "=", rec_id),
|
||||
("lang", "!=", "en_US"),
|
||||
]
|
||||
)
|
||||
for tr_res in tr_read_res:
|
||||
if not tr_res.get('lang') in values:
|
||||
values[tr_res.get('lang')] = {}
|
||||
values[tr_res.get('lang')][name] = tr_res.get('value')
|
||||
if not tr_res.get("lang") in values:
|
||||
values[tr_res.get("lang")] = {}
|
||||
values[tr_res.get("lang")][name] = tr_res.get("value")
|
||||
return res
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# Copyright 2019 Camptocamp SA
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
from odoo import models, fields
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResLang(models.Model):
|
||||
|
||||
_inherit = 'res.lang'
|
||||
_inherit = "res.lang"
|
||||
|
||||
tr_sequence = fields.Integer(
|
||||
string='Translation sequence',
|
||||
help='Defines the order of language to appear in translation dialog',
|
||||
string="Translation sequence",
|
||||
help="Defines the order of language to appear in translation dialog",
|
||||
default=10,
|
||||
)
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
||||
|
||||
.oe_translation_field {
|
||||
width: 95%;
|
||||
margin-top: 5px;
|
||||
width: 95%;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.oe_translation_field.touched {
|
||||
border: 1px solid green !important;
|
||||
border: 1px solid green !important;
|
||||
}
|
||||
.modal-xl {
|
||||
max-width: 90%;
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.oe_form_frame_cell.field_name {
|
||||
|
||||
@@ -2,183 +2,212 @@
|
||||
Copyright 2016 Antonio Espinosa <antonio.espinosa@tecnativa.com>
|
||||
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
||||
|
||||
odoo.define('web_translate_dialog.translate_dialog', function(require){
|
||||
"use strict";
|
||||
odoo.define("web_translate_dialog.translate_dialog", function(require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var BasicController = require('web.BasicController');
|
||||
var data = require('web.data');
|
||||
var Context = require('web.Context');
|
||||
var concurrency = require('web.concurrency');
|
||||
var Dialog = require('web.Dialog');
|
||||
var FormView = require('web.FormView');
|
||||
var View = require('web.AbstractView');
|
||||
var session = require('web.session');
|
||||
var rpc = require('web.rpc');
|
||||
var FormController = require('web.FormController');
|
||||
var _t = core._t;
|
||||
var QWeb = core.qweb;
|
||||
var Mutex = concurrency.Mutex;
|
||||
var core = require("web.core");
|
||||
var BasicController = require("web.BasicController");
|
||||
var data = require("web.data");
|
||||
var Context = require("web.Context");
|
||||
var concurrency = require("web.concurrency");
|
||||
var Dialog = require("web.Dialog");
|
||||
var session = require("web.session");
|
||||
var rpc = require("web.rpc");
|
||||
var FormController = require("web.FormController");
|
||||
var _t = core._t;
|
||||
var QWeb = core.qweb;
|
||||
var Mutex = concurrency.Mutex;
|
||||
|
||||
var TranslateDialog = Dialog.extend({
|
||||
template: "TranslateDialog",
|
||||
init: function(parent, options) {
|
||||
var title_string = _t("Translate fields: /");
|
||||
var field_names;
|
||||
var single_field = false;
|
||||
if (options.field){
|
||||
field_names = [options.field.fieldName];
|
||||
single_field = true;
|
||||
title_string = title_string.replace('/', field_names);
|
||||
}
|
||||
else {
|
||||
field_names = this.get_translatable_fields(parent);
|
||||
}
|
||||
this._super(parent,
|
||||
{title: title_string , size: 'x-large'});
|
||||
this.view_language = session.user_context.lang;
|
||||
this.view = parent;
|
||||
this.view_type = parent.viewType || '';
|
||||
this.translatable_fields = field_names;
|
||||
this.res_id = options.res_id;
|
||||
this.single_field = single_field;
|
||||
this.languages = null;
|
||||
this.languages_loaded = $.Deferred();
|
||||
this.lang_data = new data.DataSetSearch(
|
||||
this, 'res.lang', parent.searchView.dataset.get_context(),
|
||||
[['translatable', '=', '1']]
|
||||
);
|
||||
this.lang_data.set_sort(['tr_sequence asc','id asc']);
|
||||
this.lang_data.read_slice(['code', 'name']).then(this.on_languages_loaded);
|
||||
},
|
||||
willStart: function () {
|
||||
var self = this;
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
if (self.size == 'x-large') {
|
||||
self.$modal.find('.modal-dialog').addClass('modal-xl');
|
||||
var TranslateDialog = Dialog.extend({
|
||||
template: "TranslateDialog",
|
||||
init: function(parent, options) {
|
||||
var title_string = _t("Translate fields: /");
|
||||
var single_field = false;
|
||||
if (options.field) {
|
||||
var field_names = [options.field.fieldName];
|
||||
single_field = true;
|
||||
title_string = title_string.replace("/", field_names);
|
||||
} else {
|
||||
field_names = this.get_translatable_fields(parent);
|
||||
}
|
||||
});
|
||||
},
|
||||
get_translatable_fields: function(parent) {
|
||||
var field_list = [];
|
||||
_.each(parent.renderer.state.fields, function(field, name){
|
||||
var related_readonly = typeof field.related !== 'undefined' && field.readonly;
|
||||
if (field.translate == true && !related_readonly && parent.renderer.state.getFieldNames().includes(name)){
|
||||
field_list.push(name);
|
||||
}
|
||||
});
|
||||
return field_list;
|
||||
},
|
||||
on_languages_loaded: function(langs) {
|
||||
this.languages = langs;
|
||||
this.languages_loaded.resolve();
|
||||
},
|
||||
open: function() {
|
||||
// the template needs the languages
|
||||
return $.when(this.languages_loaded).then($.proxy(this._super, this));
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
this.$('.oe_translation_field').change(function() {
|
||||
$(this).toggleClass('touched', $(this).val() !== $(this).attr('data-value'));
|
||||
});
|
||||
this.$footer.html(QWeb.render("TranslateDialog.buttons"));
|
||||
this.$footer.find(".oe_form_translate_dialog_save_button").click(function(){
|
||||
self.on_button_save();
|
||||
self.on_button_close();
|
||||
});
|
||||
this.$footer.find(".oe_form_translate_dialog_cancel_button").click(function(){
|
||||
self.on_button_close();
|
||||
});
|
||||
|
||||
this.do_load_fields_values();
|
||||
},
|
||||
resize_textareas: function(){
|
||||
var textareas = this.$('textarea.oe_translation_field');
|
||||
var max_height = 100;
|
||||
// Resize textarea either to the max height of its content if it stays
|
||||
// in the modal or to the max height available in the modal
|
||||
if (textareas.length) {
|
||||
_.each(textareas, function(textarea) {
|
||||
if (textarea.scrollHeight > max_height) {
|
||||
max_height = textarea.scrollHeight;
|
||||
this._super(parent, {title: title_string, size: "x-large"});
|
||||
this.view_language = session.user_context.lang;
|
||||
this.view = parent;
|
||||
this.view_type = parent.viewType || "";
|
||||
this.translatable_fields = field_names;
|
||||
this.res_id = options.res_id;
|
||||
this.single_field = single_field;
|
||||
this.languages = null;
|
||||
this.languages_loaded = $.Deferred();
|
||||
this.lang_data = new data.DataSetSearch(
|
||||
this,
|
||||
"res.lang",
|
||||
parent.searchView.dataset.get_context(),
|
||||
[["translatable", "=", "1"]]
|
||||
);
|
||||
this.lang_data.set_sort(["tr_sequence asc", "id asc"]);
|
||||
this.lang_data.read_slice(["code", "name"]).then(this.on_languages_loaded);
|
||||
},
|
||||
willStart: function() {
|
||||
var self = this;
|
||||
return this._super.apply(this, arguments).then(function() {
|
||||
if (self.size === "x-large") {
|
||||
self.$modal.find(".modal-dialog").addClass("modal-xl");
|
||||
}
|
||||
});
|
||||
var max_client_height = $(window).height() - $('.modal-content').height()
|
||||
var new_height = Math.min(max_height, max_client_height)
|
||||
textareas.css({'minHeight': new_height});
|
||||
}
|
||||
},
|
||||
set_maxlength: function(){
|
||||
// set maxlength if initial field has size attr
|
||||
_.each(this.translatable_fields, function(field_name){
|
||||
var size = $('[name='+field_name+']')[0].maxLength;
|
||||
if (size > 0){
|
||||
this.$('input.oe_translation_field[name$="'+field_name+'"], textarea.oe_translation_field[name$="'+field_name+'"]').attr('maxlength', size);
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
initialize_html_fields: function(lang) {
|
||||
// Initialize summernote if HTML field
|
||||
this.$('.oe_form_field_html .oe_translation_field[name^="' + lang + '-"]').each(function() {
|
||||
var $parent = $(this).summernote({
|
||||
'focus': false,
|
||||
'toolbar': [
|
||||
['style', ['style']],
|
||||
['font', ['bold', 'italic', 'underline', 'clear']],
|
||||
['fontsize', ['fontsize']],
|
||||
['color', ['color']],
|
||||
['para', ['ul', 'ol', 'paragraph']],
|
||||
['table', ['table']],
|
||||
['insert', ['link', 'picture']],
|
||||
['misc', ['codeview']],
|
||||
['history', ['undo', 'redo']]
|
||||
],
|
||||
'prettifyHtml': false,
|
||||
'styleWithSpan': false,
|
||||
'inlinemedia': ['p'],
|
||||
'lang': "odoo",
|
||||
'onChange': function (value) {
|
||||
$(this).toggleClass('touched', value !== $(this).attr('data-value'));
|
||||
},
|
||||
get_translatable_fields: function(parent) {
|
||||
var field_list = [];
|
||||
_.each(parent.renderer.state.fields, function(field, name) {
|
||||
var related_readonly =
|
||||
typeof field.related !== "undefined" && field.readonly;
|
||||
if (
|
||||
field.translate === true &&
|
||||
!related_readonly &&
|
||||
parent.renderer.state.getFieldNames().includes(name)
|
||||
) {
|
||||
field_list.push(name);
|
||||
}
|
||||
}).parent();
|
||||
// Triggers a mouseup to refresh the editor toolbar
|
||||
$parent.find('.note-editable').trigger('mouseup');
|
||||
$parent.find('.note-editing-area').css({
|
||||
minHeight:'100px',
|
||||
minWidth:'260px',
|
||||
});
|
||||
});
|
||||
return field_list;
|
||||
},
|
||||
on_languages_loaded: function(langs) {
|
||||
this.languages = langs;
|
||||
this.languages_loaded.resolve();
|
||||
},
|
||||
open: function() {
|
||||
// The template needs the languages
|
||||
return $.when(this.languages_loaded).then($.proxy(this._super, this));
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
this.$(".oe_translation_field").change(function() {
|
||||
$(this).toggleClass(
|
||||
"touched",
|
||||
$(this).val() !== $(this).attr("data-value")
|
||||
);
|
||||
});
|
||||
this.$footer.html(QWeb.render("TranslateDialog.buttons"));
|
||||
this.$footer
|
||||
.find(".oe_form_translate_dialog_save_button")
|
||||
.click(function() {
|
||||
self.on_button_save();
|
||||
self.on_button_close();
|
||||
});
|
||||
this.$footer
|
||||
.find(".oe_form_translate_dialog_cancel_button")
|
||||
.click(function() {
|
||||
self.on_button_close();
|
||||
});
|
||||
|
||||
},
|
||||
set_fields_values: function(lang, tr_value) {
|
||||
_.each(tr_value, function(translation, field){
|
||||
this.$('.oe_translation_field[name="' + lang +
|
||||
'-' + field + '"]').val(translation || '').attr(
|
||||
'data-value', translation || '');
|
||||
}, this);
|
||||
this.initialize_html_fields(lang);
|
||||
},
|
||||
do_load_fields_values: function() {
|
||||
var self = this,
|
||||
deferred = [];
|
||||
this.do_load_fields_values();
|
||||
},
|
||||
resize_textareas: function() {
|
||||
var textareas = this.$("textarea.oe_translation_field");
|
||||
var max_height = 100;
|
||||
// Resize textarea either to the max height of its content if it stays
|
||||
// in the modal or to the max height available in the modal
|
||||
if (textareas.length) {
|
||||
_.each(textareas, function(textarea) {
|
||||
if (textarea.scrollHeight > max_height) {
|
||||
max_height = textarea.scrollHeight;
|
||||
}
|
||||
});
|
||||
var max_client_height =
|
||||
$(window).height() - $(".modal-content").height();
|
||||
var new_height = Math.min(max_height, max_client_height);
|
||||
textareas.css({minHeight: new_height});
|
||||
}
|
||||
},
|
||||
set_maxlength: function() {
|
||||
// Set maxlength if initial field has size attr
|
||||
_.each(
|
||||
this.translatable_fields,
|
||||
function(field_name) {
|
||||
var size = $("[name=" + field_name + "]")[0].maxLength;
|
||||
if (size > 0) {
|
||||
this.$(
|
||||
'input.oe_translation_field[name$="' +
|
||||
field_name +
|
||||
'"], textarea.oe_translation_field[name$="' +
|
||||
field_name +
|
||||
'"]'
|
||||
).attr("maxlength", size);
|
||||
}
|
||||
},
|
||||
this
|
||||
);
|
||||
},
|
||||
initialize_html_fields: function(lang) {
|
||||
// Initialize summernote if HTML field
|
||||
this.$(
|
||||
'.oe_form_field_html .oe_translation_field[name^="' + lang + '-"]'
|
||||
).each(function() {
|
||||
var $parent = $(this)
|
||||
.summernote({
|
||||
focus: false,
|
||||
toolbar: [
|
||||
["style", ["style"]],
|
||||
["font", ["bold", "italic", "underline", "clear"]],
|
||||
["fontsize", ["fontsize"]],
|
||||
["color", ["color"]],
|
||||
["para", ["ul", "ol", "paragraph"]],
|
||||
["table", ["table"]],
|
||||
["insert", ["link", "picture"]],
|
||||
["misc", ["codeview"]],
|
||||
["history", ["undo", "redo"]],
|
||||
],
|
||||
prettifyHtml: false,
|
||||
styleWithSpan: false,
|
||||
inlinemedia: ["p"],
|
||||
lang: "odoo",
|
||||
onChange: function(value) {
|
||||
$(this).toggleClass(
|
||||
"touched",
|
||||
value !== $(this).attr("data-value")
|
||||
);
|
||||
},
|
||||
})
|
||||
.parent();
|
||||
// Triggers a mouseup to refresh the editor toolbar
|
||||
$parent.find(".note-editable").trigger("mouseup");
|
||||
$parent.find(".note-editing-area").css({
|
||||
minHeight: "100px",
|
||||
minWidth: "260px",
|
||||
});
|
||||
});
|
||||
},
|
||||
set_fields_values: function(lang, tr_value) {
|
||||
_.each(
|
||||
tr_value,
|
||||
function(translation, field) {
|
||||
this.$('.oe_translation_field[name="' + lang + "-" + field + '"]')
|
||||
.val(translation || "")
|
||||
.attr("data-value", translation || "");
|
||||
},
|
||||
this
|
||||
);
|
||||
this.initialize_html_fields(lang);
|
||||
},
|
||||
do_load_fields_values: function() {
|
||||
var self = this,
|
||||
deferred = [];
|
||||
|
||||
this.$('.oe_translation_field').val('').removeClass('touched');
|
||||
this.$(".oe_translation_field")
|
||||
.val("")
|
||||
.removeClass("touched");
|
||||
|
||||
var def = $.Deferred();
|
||||
deferred.push(def);
|
||||
rpc.query({
|
||||
model: this.view.modelName,
|
||||
method: 'get_field_translations',
|
||||
args: [
|
||||
[this.res_id],
|
||||
],
|
||||
kwargs: {
|
||||
field_names: this.translatable_fields,
|
||||
},
|
||||
}).done(
|
||||
function (res) {
|
||||
if (res[self.res_id]){
|
||||
var def = $.Deferred();
|
||||
deferred.push(def);
|
||||
rpc.query({
|
||||
model: this.view.modelName,
|
||||
method: "get_field_translations",
|
||||
args: [[this.res_id]],
|
||||
kwargs: {
|
||||
field_names: this.translatable_fields,
|
||||
},
|
||||
}).done(function(res) {
|
||||
if (res[self.res_id]) {
|
||||
_.each(res[self.res_id], function(translation, lang) {
|
||||
self.set_fields_values(lang, translation);
|
||||
});
|
||||
@@ -188,86 +217,86 @@ var TranslateDialog = Dialog.extend({
|
||||
}
|
||||
});
|
||||
|
||||
return deferred;
|
||||
},
|
||||
on_button_save: function() {
|
||||
var translations = {},
|
||||
self = this,
|
||||
save_mutex = new Mutex();
|
||||
this.$('.oe_translation_field.touched').each(function() {
|
||||
var field = $(this).attr('name').split('-');
|
||||
if (!translations[field[0]]) {
|
||||
translations[field[0]] = {};
|
||||
}
|
||||
translations[field[0]][field[1]] = $(this).val();
|
||||
});
|
||||
_.each(translations, function(text, code) {
|
||||
save_mutex.exec(function() {
|
||||
var done = new $.Deferred(); // holds the mutex
|
||||
|
||||
var context = new Context(session.user_context, {lang: code});
|
||||
rpc.query({
|
||||
model: self.view.modelName,
|
||||
method: 'write',
|
||||
args: [self.res_id, text],
|
||||
kwargs: {context: context.eval()}
|
||||
}).then(function() {
|
||||
done.resolve();
|
||||
});
|
||||
if (code === self.view_language) {
|
||||
_.each(text, function(value, key) {
|
||||
var view_elem = self.view.$( ":input[name='" + key +"']")
|
||||
view_elem.val(value).trigger('change');
|
||||
});
|
||||
return deferred;
|
||||
},
|
||||
on_button_save: function() {
|
||||
var translations = {},
|
||||
self = this,
|
||||
save_mutex = new Mutex();
|
||||
this.$(".oe_translation_field.touched").each(function() {
|
||||
var field = $(this)
|
||||
.attr("name")
|
||||
.split("-");
|
||||
if (!translations[field[0]]) {
|
||||
translations[field[0]] = {};
|
||||
}
|
||||
return done;
|
||||
translations[field[0]][field[1]] = $(this).val();
|
||||
});
|
||||
});
|
||||
this.close();
|
||||
},
|
||||
on_button_close: function() {
|
||||
this.close();
|
||||
},
|
||||
_.each(translations, function(text, code) {
|
||||
save_mutex.exec(function() {
|
||||
var done = new $.Deferred(); // Holds the mutex
|
||||
|
||||
});
|
||||
var context = new Context(session.user_context, {lang: code});
|
||||
rpc.query({
|
||||
model: self.view.modelName,
|
||||
method: "write",
|
||||
args: [self.res_id, text],
|
||||
kwargs: {context: context.eval()},
|
||||
}).then(function() {
|
||||
done.resolve();
|
||||
});
|
||||
if (code === self.view_language) {
|
||||
_.each(text, function(value, key) {
|
||||
var view_elem = self.view.$(":input[name='" + key + "']");
|
||||
view_elem.val(value).trigger("change");
|
||||
});
|
||||
}
|
||||
return done;
|
||||
});
|
||||
});
|
||||
this.close();
|
||||
},
|
||||
on_button_close: function() {
|
||||
this.close();
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
FormController.include({
|
||||
renderSidebar: function($node) {
|
||||
this._super($node);
|
||||
if (this.sidebar) {
|
||||
var item = this.is_action_enabled('edit') && {
|
||||
label: _t('Translate'),
|
||||
callback: this.on_button_translate
|
||||
FormController.include({
|
||||
renderSidebar: function($node) {
|
||||
this._super($node);
|
||||
if (this.sidebar) {
|
||||
var item = this.is_action_enabled("edit") && {
|
||||
label: _t("Translate"),
|
||||
callback: this.on_button_translate,
|
||||
};
|
||||
if (item){
|
||||
this.sidebar.items.other.push(item);
|
||||
if (item) {
|
||||
this.sidebar.items.other.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
on_button_translate: function() {
|
||||
var self = this;
|
||||
$.when(this.has_been_loaded).then(function() {
|
||||
self.open_translate_dialog(null, self.initialState.res_id);
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
BasicController.include({
|
||||
open_translate_dialog: function(field, res_id) {
|
||||
new TranslateDialog(this, {'field': field, 'res_id': res_id}).open();
|
||||
},
|
||||
|
||||
_onTranslate: function(event) {
|
||||
// the image next to the fields opens the translate dialog
|
||||
var res_id = event.target.res_id ? event.target.res_id : event.target.state.res_id;
|
||||
this.open_translate_dialog(event.data, res_id);
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
TranslateDialog: TranslateDialog,
|
||||
};
|
||||
},
|
||||
on_button_translate: function() {
|
||||
var self = this;
|
||||
$.when(this.has_been_loaded).then(function() {
|
||||
self.open_translate_dialog(null, self.initialState.res_id);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
BasicController.include({
|
||||
open_translate_dialog: function(field, res_id) {
|
||||
new TranslateDialog(this, {field: field, res_id: res_id}).open();
|
||||
},
|
||||
|
||||
_onTranslate: function(event) {
|
||||
// The image next to the fields opens the translate dialog
|
||||
var res_id = event.target.res_id
|
||||
? event.target.res_id
|
||||
: event.target.state.res_id;
|
||||
this.open_translate_dialog(event.data, res_id);
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
TranslateDialog: TranslateDialog,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,53 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!-- Copyright 2012 Guewen Baconnier (Camptocamp SA)
|
||||
Copyright 2016 Antonio Espinosa <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
<template>
|
||||
|
||||
<t t-name="TranslateDialog">
|
||||
<div class="modal-body">
|
||||
<table t-if="widget.translatable_fields"
|
||||
class="oe_frame oe_forms oe_translation_form"
|
||||
border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<th t-if="!widget.single_field" class="oe_form_separator" width="1%" nowrap="nowrap">
|
||||
<div class="separator horizontal">Field</div>
|
||||
</th>
|
||||
<th t-foreach="widget.languages" align="left">
|
||||
<div class="separator horizontal"><t t-esc="name"/></div>
|
||||
</th>
|
||||
</tr>
|
||||
<t t-foreach="widget.translatable_fields" t-as="field_name">
|
||||
<t t-set="field" t-value="widget.view.searchView.fields[field_name]" />
|
||||
<tr t-att-data-field="field_name">
|
||||
<td t-if="!widget.single_field" class="oe_form_frame_cell field_name" width="1%" nowrap="nowrap">
|
||||
<label class="oe_label"><t t-esc="field.string"/>:</label>
|
||||
</td>
|
||||
<td t-foreach="widget.languages" t-as="lg" class="oe_form_frame_cell">
|
||||
<input t-if="['char','url'].indexOf(field.type) !== -1"
|
||||
type="text" t-attf-name="#{lg.code}-#{field_name}"
|
||||
value="" data-value="" class="oe_translation_field"/>
|
||||
<textarea t-elif="field.type == 'text'"
|
||||
t-attf-name="#{lg.code}-#{field_name}" data-value=""
|
||||
class="oe_translation_field" />
|
||||
<div t-elif="field.type == 'html'" class="oe_form_field_html">
|
||||
<textarea class="oe_translation_field oe_form_field"
|
||||
t-attf-name="#{lg.code}-#{field_name}" data-value=""/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="TranslateDialog.buttons">
|
||||
<button class="btn btn-sm oe_button btn-primary oe_form_translate_dialog_save_button">
|
||||
<span>Save</span>
|
||||
</button>
|
||||
<button class="btn btn-sm oe_button btn-default oe_form_translate_dialog_cancel_button">
|
||||
<span>Cancel</span>
|
||||
</button>
|
||||
</t>
|
||||
|
||||
<t t-name="TranslateDialog">
|
||||
<div class="modal-body">
|
||||
<table
|
||||
t-if="widget.translatable_fields"
|
||||
class="oe_frame oe_forms oe_translation_form"
|
||||
border="0"
|
||||
cellpadding="0"
|
||||
cellspacing="0"
|
||||
width="100%"
|
||||
>
|
||||
<tr>
|
||||
<th
|
||||
t-if="!widget.single_field"
|
||||
class="oe_form_separator"
|
||||
width="1%"
|
||||
nowrap="nowrap"
|
||||
>
|
||||
<div class="separator horizontal">Field</div>
|
||||
</th>
|
||||
<th t-foreach="widget.languages" align="left">
|
||||
<div class="separator horizontal">
|
||||
<t t-esc="name" />
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
<t t-foreach="widget.translatable_fields" t-as="field_name">
|
||||
<t
|
||||
t-set="field"
|
||||
t-value="widget.view.searchView.fields[field_name]"
|
||||
/>
|
||||
<tr t-att-data-field="field_name">
|
||||
<td
|
||||
t-if="!widget.single_field"
|
||||
class="oe_form_frame_cell field_name"
|
||||
width="1%"
|
||||
nowrap="nowrap"
|
||||
>
|
||||
<label class="oe_label"><t t-esc="field.string" />:</label>
|
||||
</td>
|
||||
<td
|
||||
t-foreach="widget.languages"
|
||||
t-as="lg"
|
||||
class="oe_form_frame_cell"
|
||||
>
|
||||
<input
|
||||
t-if="['char','url'].indexOf(field.type) !== -1"
|
||||
type="text"
|
||||
t-attf-name="#{lg.code}-#{field_name}"
|
||||
value=""
|
||||
data-value=""
|
||||
class="oe_translation_field"
|
||||
/>
|
||||
<textarea
|
||||
t-elif="field.type == 'text'"
|
||||
t-attf-name="#{lg.code}-#{field_name}"
|
||||
data-value=""
|
||||
class="oe_translation_field"
|
||||
/>
|
||||
<div
|
||||
t-elif="field.type == 'html'"
|
||||
class="oe_form_field_html"
|
||||
>
|
||||
<textarea
|
||||
class="oe_translation_field oe_form_field"
|
||||
t-attf-name="#{lg.code}-#{field_name}"
|
||||
data-value=""
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="TranslateDialog.buttons">
|
||||
<button
|
||||
class="btn btn-sm oe_button btn-primary oe_form_translate_dialog_save_button"
|
||||
>
|
||||
<span>Save</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm oe_button btn-default oe_form_translate_dialog_cancel_button"
|
||||
>
|
||||
<span>Cancel</span>
|
||||
</button>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="res_lang_form" model="ir.ui.view">
|
||||
<field name="name">res.lang.form.inherit</field>
|
||||
@@ -6,7 +6,10 @@
|
||||
<field name="model">res.lang</field>
|
||||
<field name="arch" type="xml">
|
||||
<field name="translatable" position="after">
|
||||
<field name="tr_sequence" attrs="{'invisible': [('translatable', '!=', True)]}" />
|
||||
<field
|
||||
name="tr_sequence"
|
||||
attrs="{'invisible': [('translatable', '!=', True)]}"
|
||||
/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2012 Guewen Baconnier (Camptocamp SA)
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
<template id="assets_backend" name="web_translate_dialog assets"
|
||||
inherit_id="web.assets_backend">
|
||||
<template
|
||||
id="assets_backend"
|
||||
name="web_translate_dialog assets"
|
||||
inherit_id="web.assets_backend"
|
||||
>
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript"
|
||||
src="/web_translate_dialog/static/src/js/web_translate_dialog.js"/>
|
||||
<link rel="stylesheet" id="translate-dialog-stylesheet"
|
||||
href="/web_translate_dialog/static/src/css/base.css"/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/web_translate_dialog/static/src/js/web_translate_dialog.js"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
id="translate-dialog-stylesheet"
|
||||
href="/web_translate_dialog/static/src/css/base.css"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user