mirror of https://github.com/OCA/web.git
Fix sidebar & reenable multiple fields
parent
239dde91b6
commit
669e4dfab3
|
@ -8,26 +8,29 @@ class BaseModel(models.BaseModel):
|
||||||
_inherit = 'base'
|
_inherit = 'base'
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def get_field_translations(self, field_name):
|
def get_field_translations(self, field_names):
|
||||||
"""Get only the existing translations for specified field
|
"""Get only the existing translations for specified field
|
||||||
|
|
||||||
:param field_name: Name of the field
|
:param field_name: Name of the field
|
||||||
:return: dict of
|
:return: dict of
|
||||||
{self.id: {'lang_code': (ir.translation,id, ir.translation,value)}}
|
{self.id: {'lang_code': {'field_name':ir.translation,value}}
|
||||||
"""
|
"""
|
||||||
read_res = self.with_context(lang='en_US').read(fields=[field_name])
|
read_res = self.with_context(lang='en_US').read(fields=field_names)
|
||||||
res = {
|
res = {}
|
||||||
rec.get('id'): {'en_US': (0, rec.get(field_name))}
|
for rec in read_res:
|
||||||
for rec in read_res
|
rec_id = rec.get('id')
|
||||||
}
|
del rec['id']
|
||||||
|
res[rec_id] = {'en_US': rec}
|
||||||
for rec_id, values in res.items():
|
for rec_id, values in res.items():
|
||||||
|
for name in field_names:
|
||||||
|
|
||||||
tr_read_res = self.env['ir.translation'].search_read([
|
tr_read_res = self.env['ir.translation'].search_read([
|
||||||
('name', '=', '%s,%s' % (self._name, field_name)),
|
('name', 'like', '%s,%s' % (self._name, field_names)),
|
||||||
('res_id', '=', rec_id),
|
('res_id', '=', rec_id),
|
||||||
('lang', '!=', 'en_US')
|
('lang', '!=', 'en_US')
|
||||||
])
|
])
|
||||||
for tr_res in tr_read_res:
|
for tr_res in tr_read_res:
|
||||||
values[tr_res.get('lang')] = (
|
if not tr_res.get('lang') in values:
|
||||||
tr_res.get('id'), tr_res.get('value')
|
values[tr_res.get('lang')] = {}
|
||||||
)
|
values[tr_res.get('lang')][name] = tr_res.get('value')
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
Go to an object that has translatable fields (*Products* for example) and
|
Go to an object that has translatable fields (*Products* for example) and
|
||||||
select *More > Translate* (or click on *Edit* and then click on the flag at
|
select *Actions > Translate* (or click on *Edit* and then click on the flag at
|
||||||
the top-right of one of the translatable fields): the translation view will
|
the top-right of one of the translatable fields): the translation view will
|
||||||
pop-up on your screen. This translation view contains all the translatable
|
pop-up on your screen. This translation view contains all the translatable
|
||||||
fields of the object.
|
fields of the object.
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
.oe_translation_field {
|
.oe_translation_field {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
.oe_translation_field.touched {
|
.oe_translation_field.touched {
|
||||||
border: 1px solid green !important;
|
border: 1px solid green !important;
|
||||||
|
@ -10,3 +11,8 @@
|
||||||
.modal-xl {
|
.modal-xl {
|
||||||
max-width: 90%;
|
max-width: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.oe_form_frame_cell.field_name {
|
||||||
|
padding-top: 5px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ var FormView = require('web.FormView');
|
||||||
var View = require('web.AbstractView');
|
var View = require('web.AbstractView');
|
||||||
var session = require('web.session');
|
var session = require('web.session');
|
||||||
var rpc = require('web.rpc');
|
var rpc = require('web.rpc');
|
||||||
|
var FormController = require('web.FormController');
|
||||||
var _t = core._t;
|
var _t = core._t;
|
||||||
var QWeb = core.qweb;
|
var QWeb = core.qweb;
|
||||||
var Mutex = concurrency.Mutex;
|
var Mutex = concurrency.Mutex;
|
||||||
|
@ -23,14 +23,25 @@ var Mutex = concurrency.Mutex;
|
||||||
var TranslateDialog = Dialog.extend({
|
var TranslateDialog = Dialog.extend({
|
||||||
template: "TranslateDialog",
|
template: "TranslateDialog",
|
||||||
init: function(parent, options) {
|
init: function(parent, options) {
|
||||||
var title_string = _t("Translate field: /")
|
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,
|
this._super(parent,
|
||||||
{title: title_string.replace('/', options.field.fieldName) , size: 'x-large'});
|
{title: title_string , size: 'x-large'});
|
||||||
this.view_language = session.user_context.lang;
|
this.view_language = session.user_context.lang;
|
||||||
this.view = parent;
|
this.view = parent;
|
||||||
this.view_type = parent.viewType || '';
|
this.view_type = parent.viewType || '';
|
||||||
this.translatable_field = options.field.fieldName;
|
this.translatable_fields = field_names;
|
||||||
this.res_id = options.res_id;
|
this.res_id = options.res_id;
|
||||||
|
this.single_field = single_field;
|
||||||
this.languages = null;
|
this.languages = null;
|
||||||
this.languages_loaded = $.Deferred();
|
this.languages_loaded = $.Deferred();
|
||||||
this.lang_data = new data.DataSetSearch(
|
this.lang_data = new data.DataSetSearch(
|
||||||
|
@ -48,6 +59,15 @@ var TranslateDialog = Dialog.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
get_translatable_fields: function(parent) {
|
||||||
|
var field_list = [];
|
||||||
|
_.each(parent.renderer.state.fields, function(field, name){
|
||||||
|
if (field.translate == true){
|
||||||
|
field_list.push(name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return field_list;
|
||||||
|
},
|
||||||
on_languages_loaded: function(langs) {
|
on_languages_loaded: function(langs) {
|
||||||
this.languages = langs;
|
this.languages = langs;
|
||||||
this.languages_loaded.resolve();
|
this.languages_loaded.resolve();
|
||||||
|
@ -74,13 +94,13 @@ var TranslateDialog = Dialog.extend({
|
||||||
},
|
},
|
||||||
resize_textareas: function(){
|
resize_textareas: function(){
|
||||||
var textareas = this.$('textarea.oe_translation_field');
|
var textareas = this.$('textarea.oe_translation_field');
|
||||||
var max_height = 100
|
var max_height = 100;
|
||||||
// Resize textarea either to the max height of its content if it stays
|
// 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
|
// in the modal or to the max height available in the modal
|
||||||
if (textareas.length) {
|
if (textareas.length) {
|
||||||
_.each(textareas, function(textarea) {
|
_.each(textareas, function(textarea) {
|
||||||
if (textarea.scrollHeight > max_height) {
|
if (textarea.scrollHeight > max_height) {
|
||||||
max_height = textarea.scrollHeight
|
max_height = textarea.scrollHeight;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var max_client_height = $(window).height() - $('.modal-content').height()
|
var max_client_height = $(window).height() - $('.modal-content').height()
|
||||||
|
@ -90,14 +110,16 @@ var TranslateDialog = Dialog.extend({
|
||||||
},
|
},
|
||||||
set_maxlength: function(){
|
set_maxlength: function(){
|
||||||
// set maxlength if initial field has size attr
|
// set maxlength if initial field has size attr
|
||||||
var size = $('[name='+this.translatable_field+']')[0].maxLength;
|
_.each(this.translatable_fields, function(field_name){
|
||||||
|
var size = $('[name='+field_name+']')[0].maxLength;
|
||||||
if (size > 0){
|
if (size > 0){
|
||||||
this.$('input.oe_translation_field, textarea.oe_translation_field').attr('maxlength', size);
|
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_html_fields: function(lang) {
|
||||||
// Initialize summernote if HTML field
|
// Initialize summernote if HTML field
|
||||||
this.$('.oe_form_field_html .oe_translation_field[name="' + lang + '-' + this.translatable_field + '"]').each(function() {
|
this.$('.oe_form_field_html .oe_translation_field[name^="' + lang + '-"]').each(function() {
|
||||||
var $parent = $(this).summernote({
|
var $parent = $(this).summernote({
|
||||||
'focus': false,
|
'focus': false,
|
||||||
'toolbar': [
|
'toolbar': [
|
||||||
|
@ -129,10 +151,11 @@ var TranslateDialog = Dialog.extend({
|
||||||
|
|
||||||
},
|
},
|
||||||
set_fields_values: function(lang, tr_value) {
|
set_fields_values: function(lang, tr_value) {
|
||||||
|
_.each(tr_value, function(translation, field){
|
||||||
this.$('.oe_translation_field[name="' + lang +
|
this.$('.oe_translation_field[name="' + lang +
|
||||||
'-' + this.translatable_field + '"]').val(tr_value || '').attr(
|
'-' + field + '"]').val(translation || '').attr(
|
||||||
'data-value', tr_value || '');
|
'data-value', translation || '');
|
||||||
|
}, this);
|
||||||
this.initialize_html_fields(lang);
|
this.initialize_html_fields(lang);
|
||||||
},
|
},
|
||||||
do_load_fields_values: function() {
|
do_load_fields_values: function() {
|
||||||
|
@ -150,13 +173,13 @@ var TranslateDialog = Dialog.extend({
|
||||||
[this.res_id],
|
[this.res_id],
|
||||||
],
|
],
|
||||||
kwargs: {
|
kwargs: {
|
||||||
field_name: this.translatable_field,
|
field_names: this.translatable_fields,
|
||||||
},
|
},
|
||||||
}).done(
|
}).done(
|
||||||
function (res) {
|
function (res) {
|
||||||
if (res[self.res_id]){
|
if (res[self.res_id]){
|
||||||
_.each(res[self.res_id], function(translation, lang) {
|
_.each(res[self.res_id], function(translation, lang) {
|
||||||
self.set_fields_values(lang, translation[1]);
|
self.set_fields_values(lang, translation);
|
||||||
});
|
});
|
||||||
self.resize_textareas();
|
self.resize_textareas();
|
||||||
self.set_maxlength();
|
self.set_maxlength();
|
||||||
|
@ -207,30 +230,30 @@ var TranslateDialog = Dialog.extend({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
FormView.include({
|
|
||||||
render_sidebar: function($node) {
|
FormController.include({
|
||||||
|
renderSidebar: function($node) {
|
||||||
this._super($node);
|
this._super($node);
|
||||||
if (this.sidebar) {
|
if (this.sidebar) {
|
||||||
this.sidebar.add_items('other', _.compact([
|
var item = this.is_action_enabled('edit') && {
|
||||||
this.is_action_enabled('edit') &&
|
|
||||||
this.translatable_field && {
|
|
||||||
label: _t('Translate'),
|
label: _t('Translate'),
|
||||||
callback: this.on_button_translate
|
callback: this.on_button_translate
|
||||||
},
|
};
|
||||||
]));
|
if (item){
|
||||||
|
this.sidebar.items.other.push(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
on_button_translate: function() {
|
on_button_translate: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
$.when(this.has_been_loaded).then(function() {
|
$.when(this.has_been_loaded).then(function() {
|
||||||
self.open_translate_dialog();
|
self.open_translate_dialog(null, self.initialState.res_id);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
BasicController.include({
|
BasicController.include({
|
||||||
|
|
||||||
open_translate_dialog: function(field, res_id) {
|
open_translate_dialog: function(field, res_id) {
|
||||||
new TranslateDialog(this, {'field': field, 'res_id': res_id}).open();
|
new TranslateDialog(this, {'field': field, 'res_id': res_id}).open();
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,17 +6,23 @@
|
||||||
|
|
||||||
<t t-name="TranslateDialog">
|
<t t-name="TranslateDialog">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<table t-if="widget.translatable_field"
|
<table t-if="widget.translatable_fields"
|
||||||
class="oe_frame oe_forms oe_translation_form"
|
class="oe_frame oe_forms oe_translation_form"
|
||||||
border="0" cellpadding="0" cellspacing="0" width="100%">
|
border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||||
<tr>
|
<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">
|
<th t-foreach="widget.languages" align="left">
|
||||||
<div class="separator horizontal"><t t-esc="name"/></div>
|
<div class="separator horizontal"><t t-esc="name"/></div>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<t t-value="widget.translatable_field" t-set="field_name" />
|
<t t-foreach="widget.translatable_fields" t-as="field_name">
|
||||||
<t t-set="field" t-value="widget.view.searchView.fields[field_name]" />
|
<t t-set="field" t-value="widget.view.searchView.fields[field_name]" />
|
||||||
<tr t-att-data-field="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">
|
<td t-foreach="widget.languages" t-as="lg" class="oe_form_frame_cell">
|
||||||
<input t-if="['char','url'].indexOf(field.type) !== -1"
|
<input t-if="['char','url'].indexOf(field.type) !== -1"
|
||||||
type="text" t-attf-name="#{lg.code}-#{field_name}"
|
type="text" t-attf-name="#{lg.code}-#{field_name}"
|
||||||
|
@ -30,6 +36,7 @@
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
</t>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
|
|
Loading…
Reference in New Issue