- body { padding: 0; margin: 0; }
+ body.openerp {
+ padding: 0;
+ margin: 0;
+ overflow-y: scroll;
+ }
.openerp {
padding: 0;
margin: 0;
height: 100%;
- overflow-y: scroll;
font-size: 80%;
font-family: Ubuntu, Helvetica, sans-serif;
}
background-color: #D2D2FF !important;
}
- .db_option_table input[type="text"], .db_option_table input[type="password"], .db_option_table select {
+ .db_option_table label {
+ display: block;
+ text-align: right;
+ }
+
+ .db_option_table input[type="text"],
+ .db_option_table input[type="password"],
+ .db_option_table input[type="file"],
+ .db_option_table select {
width: 300px;
}
height: 100%;
}
+ /* IE Hack - for IE < 9
+ * Avoids footer to be placed statically at 100% cutting the middle of the views
+ * */
+ .openerp .oe-application-container {
+ height: auto\9;
+ min-height: 100%\9;
+ }
+
/* Menu */
.openerp .menu {
height: 34px;
}
.openerp .filter_label.enabled, .openerp .filter_icon.enabled {
background: #aaa;
+ filter: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
-o-box-shadow: none;
/* Form */
-
+.openerp .oe_form_button_save_dirty {
+ display: none;
+}
+.openerp .oe_form_dirty > .oe_form_header > .oe_form_buttons > .oe_form_button_save {
+ font-weight: bold;
+}
+.openerp .oe_form_dirty > .oe_form_header > .oe_form_buttons > .oe_form_button_save > .oe_form_button_save_dirty {
+ display: inline;
+ font-weight: bold;
+ font-size: 80%;
+ position: relative;
+ bottom: 0.4em;
+}
.openerp .oe_form_frame_cell input[type="checkbox"] {
margin-top: 3px;
vertical-align: middle;
.openerp td.oe_form_frame_cell {
padding: 2px;
position: relative;
+ }
+ .openerp td.oe_form_field_translatable,
+ .openerp td.oe_form_field_many2one,
+ .openerp td.oe_form_field_date,
+ .openerp td.oe_form_field_datetime {
white-space: nowrap;
}
.openerp td.oe_form_field_boolean {
}
- .openerp label.oe_label_help, .openerp label.oe_label, .openerp .oe_forms input[type="text"], .openerp .oe_forms input[type="password"], .openerp .oe_forms select, .openerp .oe_forms .oe_button, .openerp .oe_forms textarea {
+ .openerp label.oe_label_help, .openerp label.oe_label,
+ .openerp .oe_form_paragraph,
+ .openerp .oe_form_field_statusbar,
+ .openerp .oe_forms input[type="text"],
+ .openerp .oe_forms input[type="password"],
+ .openerp .oe_forms input[type="file"],
+ .openerp .oe_forms select,
+ .openerp .oe_forms .oe_button,
+ .openerp .oe_forms textarea {
font-size: 85%;
}
white-space: normal;
}
+ .openerp .oe_forms .oe_form_paragraph.oe_multilines {
+ white-space: pre;
+ }
+
.openerp .oe_form_field_one2many .oe-actions h3.oe_view_title,
.openerp .oe_form_field_one2many_list .oe-actions h3.oe_view_title{
display: inline;
margin: 0 0.5em 0 0;
}
+ .openerp .oe_forms .oe-listview th.oe-sortable .ui-icon,
+ .openerp .oe_forms .oe-listview th.oe-sortable .ui-icon {
+ height: 100%;
+ margin-top: -9px;
+ }
+
+ .openerp table.oe_frame .oe-listview-content td {
+ color: inherit;
+ }
+
/* Uneditable Form View */
.openerp .oe_form_readonly {
min-height:100px;
}
/* Inputs */
- .openerp .oe_forms input[type="text"], .openerp .oe_forms input[type="password"], .openerp .oe_forms select, .openerp .oe_forms textarea {
+ .openerp .oe_forms input[type="text"],
+ .openerp .oe_forms input[type="password"],
+ .openerp .oe_forms input[type="file"],
+ .openerp .oe_forms select,
+ .openerp .oe_forms textarea {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
.openerp .oe_forms select{
padding-top: 2px;
}
+ .openerp .oe_forms input[readonly],
+ .openerp .oe_forms select[readonly],
+ .openerp .oe_forms textarea[readonly],
.openerp .oe_forms input[disabled],
.openerp .oe_forms select[disabled],
.openerp .oe_forms textarea[disabled]{
- background: #E0E0E0;
+ background: #E5E5E5 !important;
+ color: #666;
}
.openerp .oe_forms textarea {
resize:vertical;
}
- .openerp .oe_forms input[type="text"], .openerp .oe_forms input[type="password"], .openerp .oe_forms select, .openerp .oe_forms .oe_button {
+ .openerp .oe_forms input[type="text"],
+ .openerp .oe_forms input[type="password"],
+ .openerp .oe_forms input[type="file"],
+ .openerp .oe_forms select,
+ .openerp .oe_forms .oe_button {
height: 22px;
}
min-width: 100%;
width: 100%;
}
- .openerp .oe_forms .button {
- height: 22px;
- }
@-moz-document url-prefix() {
/* Strange firefox behaviour on width: 100% + white-space: nowrap */
.openerp .oe_forms .oe_form_button .oe_button {
width: auto;
}
}
+ /* IE Hack - for IE < 9
+ * Avoids buttons overflow
+ * */
+ .openerp .oe_forms .oe_form_button .oe_button {
+ min-width: auto\9;
+ }
+ .openerp .oe_forms .button {
+ height: 22px;
+ }
.openerp .oe_forms .oe_button span {
position: relative;
vertical-align: top;
position: absolute;
/* Should be adjusted for all browsers */
top: -2px;
- left: -700px;
+ right: 0;
opacity: 0;
filter: alpha(opacity = 0);
-ms-filter: "alpha(opacity=0)";
width: 100%;
background-color : #FFFFFF;
border-spacing: 0;
+
}
.openerp .oe-treeview-table tr:hover{
color: blue;
text-align: left;
border-bottom: 1px solid #CFCCCC;
}
- .oe-number{
+ .openerp .oe-treeview-table .oe-number {
text-align: right !important;
}
.treeview-tr span, .treeview-td span {
white-space: nowrap;
display: block;
}
- .treeview-tr:first-of-type {
+ .treeview-tr.oe-treeview-first {
background: transparent url(/web/static/src/img/expand.gif) 0 50% no-repeat;
}
- .oe-open .treeview-tr:first-of-type {
+ .oe-open .treeview-tr.oe-treeview-first {
background-image: url(/web/static/src/img/collapse.gif);
}
- .treeview-tr:first-of-type span,
- .treeview-td:first-of-type span {
+ .treeview-tr.oe-treeview-first span,
+ .treeview-td.oe-treeview-first span {
margin-left: 16px;
}
border-bottom-right-radius: 3px;
}
.openerp .oe_view_editor {
- border-collapse: collapse;
- padding: 0;
- align: left;
+ width:100%;
+ border-collapse : collapse;
+ margin-left: -12px;
+
width: 100%;
+ background-color : white;
+ border-spacing: 0;
}
- .openerp .oe_view_editor_colum{
+ .openerp .oe_view_editor td{
+ text-align: center;
+ white-space: nowrap;
+ border: 1px solid #D8D8D8;
+
+ cursor: pointer;
font-size: 90%;
- font-weight: normal;
- padding: 0;
- border-bottom: 1px solid #CFCCCC;
}
- .openerp .oe_view_editor_row:hover {
- background-color: #F3F3F3;
+ .openerp .oe_view_editor_field td{
+ border: 0px !important;
}
- .openerp .oe_view_editor_tree_grid{
- text-align: left;
- white-space: nowrap;
- border-collapse: collapse;
- width: 100%;
- }
- .openerp .oe_view_editor_tree_grid a:hover {
- color: blue;
- }
- .openerp .oe_view_editor_tree_grid a {
- display: block;
+ .openerp .oe_view_editor tr:hover {
+ background-color: #ecebf2;
}
+
/* Dialog traceback cases */
.openerp .oe_error_detail{
display: block;
this.sidebar.attachments = new openerp.web.form.SidebarAttachments(this.sidebar, this);
this.sidebar.add_toolbar(this.fields_view.toolbar);
this.set_common_sidebar_sections(this.sidebar);
+
+ this.sidebar.add_section(_t('Customize'), 'customize');
+ this.sidebar.add_items('customize', [{
+ label: _t('Set Default'),
+ form: this,
+ callback: function (item) {
+ item.form.open_defaults_dialog();
+ }
+ }]);
}
this.has_been_loaded.resolve();
},
- do_load_state: function(state) {
+ do_load_state: function(state, warm) {
if (state.id && this.datarecord.id != state.id) {
- var idx = this.dataset.get_id_index(state.id);
- if (idx === null) {
+ if (!this.dataset.get_id_index(state.id)) {
this.dataset.ids.push(state.id);
- this.dataset.index = this.dataset.ids.length - 1;
}
- this.do_show();
+ this.dataset.select_id(state.id);
+ if (warm) {
+ this.do_show();
+ }
}
},
on_record_loaded: function(record) {
var self = this, set_values = [];
if (!record) {
- throw new Error("Form: No record received");
+ this.do_warn("Form", "The record could not be found in the database.", true);
+ return $.Deferred().reject();
}
this.datarecord = record;
if (record.id) {
self.do_push_state({id:record.id});
}
+ self.$element.removeClass('oe_form_dirty');
});
},
- on_form_changed: function() {
+ on_form_changed: function(changed_by_user) {
+ if (changed_by_user) {
+ this.$element.addClass('oe_form_dirty');
+ }
for (var w in this.widgets) {
w = this.widgets[w];
w.process_modifiers();
var self = this;
return this.on_change_mutex.exec(function() {
try {
+ var response = {}, can_process_onchange = $.Deferred();
processed = processed || [];
+ processed.push(widget.name);
var on_change = widget.node.attrs.on_change;
if (on_change) {
var change_spec = self.parse_on_change(on_change, widget);
url: '/web/dataset/onchange',
async: false
};
- return self.rpc(ajax, {
+ can_process_onchange = self.rpc(ajax, {
model: self.dataset.model,
method: change_spec.method,
args: [(self.datarecord.id == null ? [] : [self.datarecord.id])].concat(change_spec.args),
context_id: change_spec.context_index == undefined ? null : change_spec.context_index + 1
- }).pipe(function(response) {
- return self.on_processed_onchange(response, processed);
+ }).then(function(r) {
+ _.extend(response, r);
});
} else {
console.warn("Wrong on_change format", on_change);
}
}
+ // fail if onchange failed
+ if (can_process_onchange.isRejected()) {
+ return can_process_onchange;
+ }
+
+ if (widget.field['change_default']) {
+ var fieldname = widget.name, value;
+ if (response.value && (fieldname in response.value)) {
+ // Use value from onchange if onchange executed
+ value = response.value[fieldname];
+ } else {
+ // otherwise get form value for field
+ value = self.fields[fieldname].get_on_change_value();
+ }
+ var condition = fieldname + '=' + value;
+
+ if (value) {
+ can_process_onchange = self.rpc({
+ url: '/web/dataset/call',
+ async: false
+ }, {
+ model: 'ir.values',
+ method: 'get_defaults',
+ args: [self.model, condition]
+ }).then(function (results) {
+ if (!results.length) { return; }
+ if (!response.value) {
+ response.value = {};
+ }
+ for(var i=0; i<results.length; ++i) {
+ // [whatever, key, value]
+ var triplet = results[i];
+ response.value[triplet[1]] = triplet[2];
+ }
+ });
+ }
+ }
+ if (can_process_onchange.isRejected()) {
+ return can_process_onchange;
+ }
+
+ return self.on_processed_onchange(response, processed);
} catch(e) {
console.error(e);
return $.Deferred().reject();
// If field is not defined in the view, just ignore it
if (field) {
var value = result.value[f];
if (field.get_value() != value) {
field.set_value(value);
field.dirty = true;
- if (_.indexOf(processed, field.name) < 0) {
+ if (!_.contains(processed, field.name)) {
this.do_onchange(field, processed);
}
}
} else {
this.datarecord.id = r.result;
if (!prepend_on_create) {
- this.dataset.ids.push(this.datarecord.id);
+ this.dataset.alter_ids(this.dataset.ids.concat([this.datarecord.id]));
this.dataset.index = this.dataset.ids.length - 1;
} else {
- this.dataset.ids.unshift(this.datarecord.id);
+ this.dataset.alter_ids([this.datarecord.id].concat(this.dataset.ids));
this.dataset.index = 0;
}
this.do_update_pager();
},
sidebar_context: function () {
return this.do_save().pipe(_.bind(function() {return this.get_fields_values();}, this));
+ },
+ open_defaults_dialog: function () {
+ var self = this;
+ var fields = _.chain(this.fields)
+ .map(function (field, name) {
+ var value = field.get_value();
+ // ignore fields which are empty, invisible, readonly, o2m
+ // or m2m
+ if (!value
+ || field.invisible
+ || field.readonly
+ || field.field.type === 'one2many'
+ || field.field.type === 'many2many') {
+ return false;
+ }
+ var displayed;
+ switch(field.field.type) {
+ case 'selection':
+ displayed = _(field.values).find(function (option) {
+ return option[0] === value;
+ })[1];
+ break;
+ case 'many2one':
+ displayed = field.value[1] || value;
+ break;
+ default:
+ displayed = value;
+ }
+
+ return {
+ name: name,
+ string: field.string,
+ value: value,
+ displayed: displayed,
+ // convert undefined to false
+ change_default: !!field.field.change_default
+ }
+ })
+ .compact()
+ .sortBy(function (field) { return field.string; })
+ .value();
+ var conditions = _.chain(fields)
+ .filter(function (field) { return field.change_default; })
+ .value();
+
+ var d = new openerp.web.Dialog(this, {
+ title: _t("Set Default"),
+ args: {
+ fields: fields,
+ conditions: conditions
+ },
+ buttons: [
+ {text: _t("Close"), click: function () { d.close(); }},
+ {text: _t("Save default"), click: function () {
+ var $defaults = d.$element.find('#formview_default_fields');
+ var field_to_set = $defaults.val();
+ if (!field_to_set) {
+ $defaults.parent().addClass('invalid');
+ return;
+ }
+ var condition = d.$element.find('#formview_default_conditions').val(),
+ all_users = d.$element.find('#formview_default_all').is(':checked');
+ new openerp.web.DataSet(self, 'ir.values').call(
+ 'set_default', [
+ self.dataset.model,
+ field_to_set,
+ self.fields[field_to_set].get_value(),
+ all_users,
+ false,
+ condition || false
+ ]).then(function () { d.close(); });
+ }}
+ ]
+ });
+ d.template = 'FormView.set_default';
+ d.open();
}
});
openerp.web.FormDialog = openerp.web.Dialog.extend({
stack.push(!top);
continue;
default:
- throw new Error('Unknown domain operator ' + ex);
+ throw new Error(_.str.sprintf(
+ _t("Unknown operator %s in domain %s"),
+ ex, JSON.stringify(expr)));
}
}
var field = fields[ex[0]];
if (!field) {
- throw new Error("Domain references unknown field : " + ex[0]);
+ throw new Error(_.str.sprintf(
+ _t("Unknown field %s in domain %s"),
+ ex[0], JSON.stringify(expr)));
}
var field_value = field.get_value ? fields[ex[0]].get_value() : fields[ex[0]].value;
var op = ex[1];
stack.push(!_(val).contains(field_value));
break;
default:
- console.warn("Unsupported operator in modifiers :", op);
+ console.warn(
+ _t("Unsupported operator %s in domain %s"),
+ op, JSON.stringify(expr));
}
}
return _.all(stack, _.identity);
},
stop: function() {
this._super.apply(this, arguments);
- $('div.tipsy').stop().remove();
+ $.fn.tipsy.clear();
},
process_modifiers: function() {
var compute_domain = openerp.web.form.compute_domain;
debug: openerp.connection.debug,
widget: widget
})},
- gravity: $.fn.tipsy.autoNS,
+ gravity: $.fn.tipsy.autoBounds(50, 'nw'),
html: true,
opacity: 0.85,
trigger: 'hover'
this._super(view, node);
+ if (this.node.tag == 'label' && !this.string && this.node.children.length) {
+ this.string = this.node.children[0];
+ this.align = 'left';
+ }
+
if (this.node.tag == 'label' && (this.align === 'left' || this.node.attrs.colspan || (this.string && this.string.length > 32))) {
this.template = "WidgetParagraph";
this.colspan = parseInt(this.node.attrs.colspan || 1, 10);
if (isNaN(parseFloat(this.node.attrs.align))) {
this.align = 'left';
}
+
+ this.multilines = this.string && _.str.lines(this.string).length > 1;
} else {
this.colspan = 1;
this.width = '1%';
this._super.apply(this, arguments);
if (this.field.translate) {
this.view.translatable_fields.push(this);
+ this.$element.addClass('oe_form_field_translatable');
this.$element.find('.oe_field_translate').click(this.on_translate);
}
if (this.nolabel && openerp.connection.debug) {
if (this.is_valid()) {
this.set_value_from_ui();
this.view.do_onchange(this);
- this.view.on_form_changed();
+ this.view.on_form_changed(true);
} else {
this.update_dom(true);
}
},
update_dom: function() {
this._super.apply(this, arguments);
- this.$element.find('input').prop('disabled', this.readonly);
+ this.$element.find('input').prop('readonly', this.readonly);
},
set_value_from_ui: function() {
this.value = openerp.web.parse_value(this.$element.find('input').val(), this);
openerp.web.form.FieldID = openerp.web.form.FieldChar.extend({
update_dom: function() {
this._super.apply(this, arguments);
- this.$element.find('input').prop('disabled', true);
+ this.$element.find('input').prop('readonly', true);
}
});
showButtonPanel: true
});
this.$element.find('img.oe_datepicker_trigger').click(function() {
- if (!self.readonly) {
+ if (!self.readonly && !self.picker('widget').is(':visible')) {
self.picker('setDate', self.value ? openerp.web.auto_str_to_date(self.value) : new Date());
self.$input_picker.show();
self.picker('show');
},
set_readonly: function(readonly) {
this.readonly = readonly;
- this.$input.prop('disabled', this.readonly);
+ this.$input.prop('readonly', this.readonly);
this.$element.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', readonly);
},
is_valid: function(required) {
},
update_dom: function() {
this._super.apply(this, arguments);
- this.$element.find('textarea').prop('disabled', this.readonly);
+ this.$element.find('textarea').prop('readonly', this.readonly);
},
set_value_from_ui: function() {
this.value = openerp.web.parse_value(this.$element.find('textarea').val(), this);
self.last_search = data;
// possible selections for the m2o
var values = _.map(data, function(x) {
- return {label: $('<span />').text(x[1]).html(), name:x[1], id:x[0]};
+ return {
+ label: _.str.escapeHTML(x[1]),
+ value:x[1],
+ name:x[1],
+ id:x[0]
+ };
});
// search more... if more results that max
},
update_dom: function() {
this._super.apply(this, arguments);
- this.$input.prop('disabled', this.readonly);
+ this.$input.prop('readonly', this.readonly);
}
});
this.viewmanager = new openerp.web.ViewManager(this, this.dataset, views, {});
this.viewmanager.template = 'One2Many.viewmanager';
- this.viewmanager.registry = openerp.web.views.clone({
+ this.viewmanager.registry = openerp.web.views.extend({
list: 'openerp.web.form.One2ManyListView',
form: 'openerp.web.form.One2ManyFormView',
page: 'openerp.web.PageView'
obj['id'] = _.uniqueId(self.dataset.virtual_id_prefix);
obj.defaults = {};
self.dataset.to_create.push(obj);
- self.dataset.cache.push(_.clone(obj));
+ self.dataset.cache.push(_.extend(_.clone(obj), {values: _.clone(command[2])}));
ids.push(obj.id);
return;
case commands.UPDATE:
obj['id'] = command[1];
self.dataset.to_write.push(obj);
- self.dataset.cache.push(_.clone(obj));
+ self.dataset.cache.push(_.extend(_.clone(obj), {values: _.clone(command[2])}));
ids.push(obj.id);
return;
case commands.DELETE:
contexts, groupbys);
self.initial_ids = undefined;
} else {
- self.do_search(domains.concat([self.domain]), contexts, groupbys);
+ self.do_search(domains.concat([self.domain]), contexts.concat(self.context), groupbys);
}
});
this.searchview.on_loaded.add_last(function () {
on_file_uploaded_and_valid: function(size, name, content_type, file_base64) {
},
on_save_as: function() {
- var url = '/web/binary/saveas?session_id=' + this.session.session_id + '&model=' +
- this.view.dataset.model +'&id=' + (this.view.datarecord.id || '') + '&field=' + this.name +
- '&filename_field=' + (this.node.attrs.filename || '') + '&t=' + (new Date().getTime());
- window.open(url);
+ $.blockUI();
+ this.session.get_file({
+ url: '/web/binary/saveas_ajax',
+ data: {data: JSON.stringify({
+ model: this.view.dataset.model,
+ id: (this.view.datarecord.id || ''),
+ field: this.name,
+ filename_field: (this.node.attrs.filename || ''),
+ context: this.view.dataset.get_context()
+ })},
+ complete: $.unblockUI,
+ error: openerp.webclient.crashmanager.on_rpc_error
+ });
},
on_clear: function() {
if (this.value !== false) {
update_dom: function() {
this._super.apply(this, arguments);
this.$element.find('.oe-binary-file-set, .oe-binary-file-clear').toggle(!this.readonly);
- this.$element.find('input[type=text]').prop('disabled', this.readonly);
+ this.$element.find('input[type=text]').prop('readonly', this.readonly);
},
set_value: function(value) {
this._super.apply(this, arguments);
-->
<templates id="template" xml:space="preserve">
<t t-name="Notification">
- <div class="oe_notification">
+ <div class="oe_notification" t-translation="off">
<div id="oe_notification_default">
<a class="ui-notify-cross ui-notify-close" href="#">x</a>
<h1>#{title}</h1>
<option t-att-value="db"><t t-esc="db"/></option>
</t>
</select>
+ <input t-if="!db_list" name="drop_db" class="required"
+ type="text" autofocus="autofocus"/>
</td>
</tr>
<tr>
<option t-att-value="db"><t t-esc="db"/></option>
</t>
</select>
+ <input t-if="!db_list" name="drop_db" class="required"
+ type="text" autofocus="autofocus"/>
</td>
</tr>
<tr>
</t>
<t t-name="Menu.secondary">
<div t-attf-class="oe_toggle_secondary_menu">
- <span class="oe_menu_fold" title="Fold menu">&laquo;</span>
- <span class="oe_menu_unfold" title="Unfold menu">&raquo;</span>
+ <span class="oe_menu_fold" title="Fold menu"><t t-raw="'&laquo;'"/></span>
+ <span class="oe_menu_unfold" title="Unfold menu"><t t-raw="'&raquo;'"/></span>
</div>
<div t-foreach="widget.data.data.children" t-as="menu" style="display: none" class="oe_secondary_menu" t-att-data-menu-parent="menu.id">
<t t-foreach="menu.children" t-as="menu">
- <t t-set="classname">oe_secondary_menu_item</t>
+ <t t-set="classname" t-translation="off">oe_secondary_menu_item</t>
<t t-set="level" t-value="0"/>
<t t-call="Menu.secondary.children"/>
</t>
</a>
<div t-attf-class="oe_secondary_submenu" t-if="menu.children.length" t-att-style="menu_first and level == 1 ? undefined : 'display: none'">
<t t-foreach="menu.children" t-as="menu">
- <t t-set="classname">oe_secondary_submenu_item</t>
+ <t t-set="classname" t-translation="off">oe_secondary_submenu_item</t>
<t t-call="Menu.secondary.children"/>
</t>
</div>
<div class="oe_vm_switch">
<t t-if="views.length != 1" t-foreach="views" t-as="view">
- <button type="button" t-attf-class="oe_vm_switch_#{view.view_type}" t-att-data-view-type="view.view_type" t-att-title="view.view_type">
+ <button type="button" t-attf-class="oe_vm_switch_#{view.view_type}" t-att-data-view-type="view.view_type" t-att-title="view.label || view.view_type">
<span><t t-esc="view.label || view.view_type"/></span>
</button>
</t>
<option t-if="view_manager.searchview" value="edit" data-model="ir.ui.view" t-att-data-id="view_manager.searchview.view_id">Edit SearchView</option>
<option t-if="view_manager.action" value="edit" t-att-data-model="view_manager.action.type" t-att-data-id="view_manager.action.id">Edit Action</option>
<option value="edit_workflow">Edit Workflow</option>
- <option value="customize_object">Customize Object</option>
</t>
</t>
<t t-name="ViewManagerDebugViewLog">
</div>
</t>
<t t-name="Sidebar.section.items">
- <li t-foreach="items" t-as="item" t-att-class="item.classname">
- <a class="oe_sidebar_action_a" t-att-id="item.element_id" t-att-title="item.title" href="#">
- <t t-esc="item.label"/>
- </a>
- </li>
+ <li t-foreach="items" t-as="item" t-att-class="item.classname">
+ <a class="oe_sidebar_action_a" t-att-id="item.element_id" t-att-title="item.title" href="#">
+ <t t-esc="item.label"/>
+ </a>
+ </li>
</t>
<t t-name="TranslateDialog">
t-att-data-id="record.id" t-att-data-level="level + 1">
<t t-set="children" t-value="record[children_field]"/>
<t t-set="class" t-value="children and children.length ? 'treeview-tr' : 'treeview-td'"/>
+ <t t-set="rank" t-value="'oe-treeview-first'"/>
<t t-set="style" t-value="'background-position: ' + 19*level + 'px; padding-left: ' + 19*level + 'px;'"/>
<td t-foreach="fields_view" t-as="field"
t-if="!field.attrs.modifiers.tree_invisible"
t-att-data-id="record.id"
t-att-style="color_for(record) + style "
- t-att-class="(fields[field.attrs.name].type === 'float') or (fields[field.attrs.name].type === 'integer')
- ? (class +' ' +'oe-number') : class">
+ t-attf-class="#{class} #{rank} #{(fields[field.attrs.name].type === 'float') or (fields[field.attrs.name].type === 'integer') ? 'oe-number' : ''}">
<span t-if="!field.attrs.modifiers.invisible" >
<t t-esc="render(record[field.attrs.name], fields[field.attrs.name])" />
</span>
<t t-set="class" t-value="'treeview-td'"/>
+ <t t-set="rank" t-value="''"/>
<t t-set="style" t-value="''"/>
</td>
</tr>
<t t-jquery="td.oe-actions">
this.removeAttr('t-if');
- var $title = $(document.createElement('h3')).addClass('oe_view_title');
- $title.append($(document.createElement('t')).attr(
- 't-esc', 'fields_view.arch.attrs.string'));
- this.prepend($title);
+ </t>
+ <t t-jquery="td.oe-actions" t-operation="prepend">
+ <h3 class="oe_view_title"><t t-esc="fields_view.arch.attrs.string"/></h3>
</t>
</t>
<th t-name="Listview.navigation.button" t-if="!no_leaf and options.pager !== false"
<t t-name="FormView">
<div class="oe_form_header">
<div class="oe_form_buttons" t-if="widget.options.action_buttons !== false">
- <button type="button" class="oe_button oe_form_button_save">Save</button>
+ <button type="button" class="oe_button oe_form_button_save">
+ Save
+ <span class="oe_form_button_save_dirty">(*)</span>
+ </button>
<button type="button" class="oe_button oe_form_button_cancel">Cancel</button>
</div>
<div class="oe_form_pager" t-if="widget.options.pager !== false">
</li>
</ul>
</t>
+ <form t-name="FormView.set_default" class="oe_forms oe_frame">
+ <t t-set="args" t-value="widget.dialog_options.args"/>
+ <table style="width: 100%">
+ <tr>
+ <td>
+ <label for="formview_default_fields"
+ class="oe_label oe_align_right">
+ Default:
+ </label>
+ </td>
+ <td class="required">
+ <select id="formview_default_fields">
+ <option value=""/>
+ <option t-foreach="args.fields" t-as="field"
+ t-att-value="field.name">
+ <t t-esc="field.string"/> = <t t-esc="field.displayed"/>
+ </option>
+ </select>
+ </td>
+ </tr>
+ <tr t-if="args.conditions.length">
+ <td>
+ <label for="formview_default_conditions"
+ class="oe_label oe_align_right">
+ Condition:
+ </label>
+ </td>
+ <td>
+ <select id="formview_default_conditions">
+ <option value=""/>
+ <option t-foreach="args.conditions" t-as="cond"
+ t-att-value="cond.name + '=' + cond.value">
+ <t t-esc="cond.string"/>=<t t-esc="cond.displayed"/>
+ </option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <input type="radio" id="formview_default_self"
+ value="self" name="scope" checked="checked"/>
+ <label for="formview_default_self" class="oe_label"
+ style="display: inline;">
+ Only you
+ </label>
+ <br/>
+ <input type="radio" id="formview_default_all"
+ value="all" name="scope"/>
+ <label for="formview_default_all" class="oe_label"
+ style="display: inline;">
+ All users
+ </label>
+ </td>
+ </tr>
+ </table>
+ </form>
<t t-name="Widget">
Unhandled widget
<t t-js="dict">console.warn('Unhandled widget', dict.widget);</t>
<span class="oe_tooltip_technical_title">Modifiers:</span>
<t t-esc="widget.node.attrs.modifiers"/>
</li>
+ <li t-if="widget.field and widget.field.change_default" data-item="change_default">
+ <span class="oe_tooltip_technical_title">Change default:</span>
+ Yes
+ </li>
<li t-if="widget.node.attrs.on_change" data-item="on_change">
<span class="oe_tooltip_technical_title">On change:</span>
<t t-esc="widget.node.attrs.on_change"/>
</ul>
</t>
<t t-name="WidgetParagraph">
- <p t-attf-class="oe_form_paragraph oe_align_#{widget.align}"><t t-esc="widget.string"/></p>
+ <p t-attf-class="oe_form_paragraph oe_align_#{widget.align} #{widget.multilines ? 'oe_multilines' : ''}"><t t-esc="widget.string"/></p>
</t>
<t t-name="FieldChar">
<input t-att-type="widget.password ? 'password' : 'text'" size="1"
</t>
<t t-name="FieldURI.readonly">
<div>
- <a href="#" class="oe_form_uri">#</a>
+ <a href="#" class="oe_form_uri"/>
</div>
</t>
<t t-name="FieldEmail">
<option class="oe-filters-title" value="">Filters</option>
<optgroup label="-- Filters --">
<t t-foreach="filters" t-as="filter">
- <option t-attf-value="get:#{filter_index}"><t t-esc="filter.name"/></option>
+ <option t-attf-value="get:#{filter_index}"
+ t-att-disabled="filter.disabled and 'disabled'"
+ t-att-title="filter.disabled and disabled_filter_message">
+ <t t-esc="filter.name"/>
+ </option>
</t>
</optgroup>
<optgroup label="-- Actions --">
<span t-if="attrs.help">?</span>
</label>
<div t-att-style="style">
- <span t-att-id="element_id"></span>
+ <span t-att-id="element_id"/>
<t t-if="filters.length" t-raw="filters.render(defaults)"/>
</div>
</t>
<t t-foreach="attrs.selection" t-as="option">
<t t-set="selected" t-value="defaults[attrs.name] === option[0]"/>
<option t-if="selected"
- t-att-value="option_index" selected="selected">
+ t-attf-selected="selected"
+ t-att-value="option_index">
<t t-esc="option[1]"/>
</option>
<option t-if="!selected" t-att-value="option_index">
</table>
</t>
<t t-name="view_editor.row">
- <tr class="oe_view_editor_row" t-att-id="'viewedit-' + rec.id" t-att-level="rec.level" t-foreach="data" t-as="rec">
- <td class="oe_view_editor_colum" width="85%">
- <table class="oe_view_editor_tree_grid">
+ <tr t-att-id="'viewedit-' + rec.id" t-att-level="rec.level" t-foreach="data" t-as="rec">
+ <td width="90%">
+ <table class="oe_view_editor_field">
<tr>
<td width="16px" t-att-style="'background-position: ' + 20*rec.level + 'px; padding-left: ' + 20*rec.level + 'px'">
<img t-if="rec.child_id.length" t-att-id="'parentimg-' + rec.id"
</tr>
</table>
</td>
- <td align="left" class="oe_view_editor_colum" width="15%">
- <table width="100%">
- <tr>
- <td width="20%">
- <img t-if="rec.att_list.length"
- id="side-add" src="/web/static/src/img/icons/gtk-add.png" style="cursor: pointer;"/>
- </td>
- <td width="20%">
- <img id="side-remove" src="/web/static/src/img/icons/gtk-remove.png" style="cursor: pointer;"/>
- </td>
- <td width="20%">
- <img t-if="rec.att_list.length and !_.include(no_properties, rec.att_list[0])"
- id="side-edit" src="/web/static/src/img/icons/gtk-edit.png" style="cursor: pointer;"/>
- </td>
- <td width="20%">
- <img t-if="rec.att_list.length"
- id="side-up" src="/web/static/src/img/icons/gtk-go-up.png" style="cursor: pointer;"/>
- </td>
- <td width="20%">
- <img t-if="rec.att_list.length"
- id="side-down" src="/web/static/src/img/icons/gtk-go-down.png" style="cursor: pointer;"/>
- </td>
- </tr>
- </table>
+ <td width="2%">
+ <img t-if="rec.att_list.length"
+ id="side-add" src="/web/static/src/img/icons/gtk-add.png" style="cursor: pointer;"/>
+ </td>
+ <td width="2%">
+ <img id="side-remove" src="/web/static/src/img/icons/gtk-remove.png" style="cursor: pointer;"/>
+ </td>
+ <td width="2%">
+ <img t-if="rec.att_list.length and !_.include(no_properties, rec.att_list[0])"
+ id="side-edit" src="/web/static/src/img/icons/gtk-edit.png" style="cursor: pointer;"/>
+ </td>
+ <td width="2%">
+ <img t-if="rec.att_list.length"
+ id="side-up" src="/web/static/src/img/icons/gtk-go-up.png" style="cursor: pointer;"/>
+ </td>
+ <td width="2%">
+ <img t-if="rec.att_list.length"
+ id="side-down" src="/web/static/src/img/icons/gtk-go-down.png" style="cursor: pointer;"/>
</td>
<t t-if="rec.child_id.length">
<t t-set="data" t-value="rec.child_id"/>
<tr class="oe_export_row">
<t t-foreach="(field.id).split('/')" t-as="level" >
<t t-if="(field.id).split('/')[0] != level">
- <td width="18">&nbsp;</td>
+ <td width="18" t-translation="off">&nbsp;</td>
</t>
</t>
<td valign="top" align="left" style="cursor: pointer;" width="18">