[MERGE] with branch lp:openerp-web
bzr revid: jam@tinyerp.com-20120608044656-kikgqc5wm9qzimse
This commit is contained in:
@@ -1467,6 +1467,10 @@ class Binary(openerpweb.Controller):
|
||||
|
||||
class Action(openerpweb.Controller):
|
||||
_cp_path = "/web/action"
|
||||
|
||||
action_mapping = {
|
||||
"ir.actions.act_url": "ir.actions.url",
|
||||
}
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def load(self, req, action_id, do_not_eval=False):
|
||||
@@ -1479,7 +1483,9 @@ class Action(openerpweb.Controller):
|
||||
if action_type[0]['type'] == 'ir.actions.report.xml':
|
||||
ctx.update({'bin_size': True})
|
||||
ctx.update(context)
|
||||
action = req.session.model(action_type[0]['type']).read([action_id], False, ctx)
|
||||
action_model = action_type[0]['type']
|
||||
action_model = Action.action_mapping.get(action_model, action_model)
|
||||
action = req.session.model(action_model).read([action_id], False, ctx)
|
||||
if action:
|
||||
value = clean_action(req, action[0], do_not_eval)
|
||||
return {'result': value}
|
||||
|
||||
@@ -1629,7 +1629,7 @@
|
||||
font-weight: bold;
|
||||
color: #b33630;
|
||||
}
|
||||
.openerp .oe_form_readonly header.oe_form_topbar_hifirst button:first-child, .openerp .oe_form_readonly button.oe_form_button_hi {
|
||||
.openerp .oe_form_readonly button.oe_form_button_hi {
|
||||
color: white;
|
||||
background: #dc5f59;
|
||||
background: -moz-linear-gradient(#dc5f59, #b33630);
|
||||
@@ -1639,7 +1639,7 @@
|
||||
-webkit-box-shadow: none;
|
||||
-box-shadow: none;
|
||||
}
|
||||
.openerp .oe_form_readonly header.oe_form_topbar_hifirst button:first-child:hover, .openerp .oe_form_readonly button.oe_form_button_hi:hover {
|
||||
.openerp .oe_form_readonly button.oe_form_button_hi:hover {
|
||||
background: #df6b66;
|
||||
background: -moz-linear-gradient(#df6b66, #bf3a33);
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#df6b66), to(#bf3a33));
|
||||
@@ -1667,13 +1667,13 @@
|
||||
-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||
-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.openerp .oe_form_invisible {
|
||||
display: none;
|
||||
}
|
||||
.openerp .oe_form_editable .oe_form_editable_hidden {
|
||||
display: none;
|
||||
}
|
||||
.openerp .oe_form_readonly .oe_form_readonly_hidden {
|
||||
display: none;
|
||||
}
|
||||
.openerp .oe_form_readonly .oe_form_field:empty {
|
||||
.openerp .oe_form_readonly .oe_form_readonly_hidden, .openerp .oe_form_readonly .oe_form_field:empty {
|
||||
display: none;
|
||||
}
|
||||
.openerp .oe_form .oe_form_field_text {
|
||||
@@ -1723,7 +1723,7 @@
|
||||
}
|
||||
.openerp .oe_form .oe_form_field {
|
||||
width: 100%;
|
||||
display: inline-block !important;
|
||||
display: inline-block;
|
||||
padding: 2px 2px 2px 0px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
@@ -1287,7 +1287,7 @@ $colour4: #8a89ba
|
||||
font-weight: bold
|
||||
color: #b33630
|
||||
.oe_form_readonly
|
||||
header.oe_form_topbar_hifirst button:first-child, button.oe_form_button_hi
|
||||
button.oe_form_button_hi
|
||||
color: white
|
||||
background: #DC5F59
|
||||
background: -moz-linear-gradient(#DC5F59, #B33630)
|
||||
@@ -1296,7 +1296,7 @@ $colour4: #8a89ba
|
||||
-moz-box-shadow: none
|
||||
-webkit-box-shadow: none
|
||||
-box-shadow: none
|
||||
header.oe_form_topbar_hifirst button:first-child:hover, button.oe_form_button_hi:hover
|
||||
button.oe_form_button_hi:hover
|
||||
background: #DF6B66
|
||||
background: -moz-linear-gradient( #DF6B66, #BF3A33)
|
||||
background: -webkit-gradient(linear, left top, left bottom, from( #DF6B66), to( #BF3A33))
|
||||
@@ -1321,12 +1321,13 @@ $colour4: #8a89ba
|
||||
@include box-shadow(0 0 10px rgba(0,0,0,0.3))
|
||||
// }}}
|
||||
// FormView.layout {{{
|
||||
.oe_form_invisible
|
||||
display: none
|
||||
.oe_form_editable .oe_form_editable_hidden
|
||||
display: none
|
||||
.oe_form_readonly .oe_form_readonly_hidden
|
||||
display: none
|
||||
.oe_form_readonly .oe_form_field:empty
|
||||
display: none
|
||||
.oe_form_readonly
|
||||
.oe_form_readonly_hidden, .oe_form_field:empty
|
||||
display: none
|
||||
.oe_form
|
||||
.oe_form_field_text
|
||||
width: 100%
|
||||
@@ -1376,8 +1377,7 @@ $colour4: #8a89ba
|
||||
resize: vertical
|
||||
.oe_form_field
|
||||
width: 100%
|
||||
// Using !important because jQuery's $.fn.show() will set display to 'inline' for spans
|
||||
display: inline-block !important
|
||||
display: inline-block
|
||||
padding: 2px 2px 2px 0px
|
||||
line-height: 18px
|
||||
input
|
||||
|
||||
@@ -208,8 +208,9 @@ instance.web.FormView = instance.web.View.extend(_.extend({}, instance.web.form.
|
||||
}
|
||||
}
|
||||
},
|
||||
do_show: function () {
|
||||
do_show: function (options) {
|
||||
var self = this;
|
||||
options = options || {};
|
||||
if (this.sidebar) {
|
||||
this.sidebar.$element.show();
|
||||
}
|
||||
@@ -233,6 +234,9 @@ instance.web.FormView = instance.web.View.extend(_.extend({}, instance.web.form.
|
||||
}).pipe(self.on_record_loaded);
|
||||
}
|
||||
result.pipe(function() {
|
||||
if (options.editable) {
|
||||
self.set({mode: "edit"});
|
||||
}
|
||||
self.$element.css('visibility', 'visible');
|
||||
});
|
||||
return result;
|
||||
@@ -495,7 +499,8 @@ instance.web.FormView = instance.web.View.extend(_.extend({}, instance.web.form.
|
||||
this.on_form_changed();
|
||||
}
|
||||
if (!_.isEmpty(result.warning)) {
|
||||
instance.web.dialog($(QWeb.render("CrashManagerWarning", result.warning)), {
|
||||
instance.web.dialog($(QWeb.render("CrashManager.warning", result.warning)), {
|
||||
title:result.warning.title,
|
||||
modal: true,
|
||||
buttons: [
|
||||
{text: _t("Ok"), click: function() { $(this).dialog("close"); }}
|
||||
@@ -642,6 +647,9 @@ instance.web.FormView = instance.web.View.extend(_.extend({}, instance.web.form.
|
||||
}
|
||||
if (form_invalid) {
|
||||
self.set({'display_invalid_fields': true});
|
||||
for (var f in self.fields) {
|
||||
self.fields[f]._check_css_flags();
|
||||
}
|
||||
first_invalid_field.focus();
|
||||
self.on_invalid();
|
||||
return $.Deferred().reject();
|
||||
@@ -1191,19 +1199,40 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
|
||||
var $page = $(this);
|
||||
var page_attrs = $page.getAttributes();
|
||||
page_attrs.id = _.uniqueId('notebook_page_');
|
||||
pages.push(page_attrs);
|
||||
var $new_page = self.render_element('FormRenderingNotebookPage', page_attrs);
|
||||
$page.contents().appendTo($new_page);
|
||||
$page.before($new_page).remove();
|
||||
self.handle_common_properties($new_page, $page);
|
||||
var ic = self.handle_common_properties($new_page, $page).invisibility_changer;
|
||||
page_attrs.__page = $new_page;
|
||||
page_attrs.__ic = ic;
|
||||
pages.push(page_attrs);
|
||||
|
||||
$new_page.children().each(function() {
|
||||
self.process($(this));
|
||||
});
|
||||
});
|
||||
var $new_notebook = this.render_element('FormRenderingNotebook', { pages : pages });
|
||||
$notebook.contents().appendTo($new_notebook);
|
||||
$notebook.before($new_notebook).remove();
|
||||
$new_notebook.children().each(function() {
|
||||
self.process($(this));
|
||||
});
|
||||
self.process($($new_notebook.children()[0]));
|
||||
//tabs and invisibility handling
|
||||
$new_notebook.tabs();
|
||||
_.each(pages, function(page, i) {
|
||||
if (! page.__ic)
|
||||
return;
|
||||
page.__ic.on("change:effective_invisible", null, function() {
|
||||
var current = $new_notebook.tabs("option", "selected");
|
||||
if (! pages[current].__ic || ! pages[current].__ic.get("effective_invisible"))
|
||||
return;
|
||||
var first_visible = _.find(_.range(pages.length), function(i2) {
|
||||
return (! pages[i2].__ic) || (! pages[i2].__ic.get("effective_invisible"));
|
||||
});
|
||||
if (first_visible !== undefined) {
|
||||
$new_notebook.tabs('select', first_visible);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.handle_common_properties($new_notebook, $notebook);
|
||||
return $new_notebook;
|
||||
},
|
||||
@@ -1241,10 +1270,12 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
|
||||
handle_common_properties: function($new_element, $node) {
|
||||
var str_modifiers = $node.attr("modifiers") || "{}"
|
||||
var modifiers = JSON.parse(str_modifiers);
|
||||
var ic = null;
|
||||
if (modifiers.invisible !== undefined)
|
||||
new instance.web.form.InvisibilityChanger(this.view, this.view, modifiers.invisible, $new_element);
|
||||
ic = new instance.web.form.InvisibilityChanger(this.view, this.view, modifiers.invisible, $new_element);
|
||||
$new_element.addClass($node.attr("class") || "");
|
||||
$new_element.attr('style', $node.attr('style'));
|
||||
return {invisibility_changer: ic,};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1386,11 +1417,7 @@ instance.web.form.InvisibilityChangerMixin = {
|
||||
this._check_visibility();
|
||||
},
|
||||
_check_visibility: function() {
|
||||
if (this.get("effective_invisible")) {
|
||||
this.$element.hide();
|
||||
} else {
|
||||
this.$element.show();
|
||||
}
|
||||
this.$element.toggleClass('oe_form_invisible', this.get("effective_invisible"));
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1879,7 +1906,7 @@ instance.web.form.FieldChar = instance.web.form.AbstractField.extend(_.extend({}
|
||||
return true;
|
||||
},
|
||||
is_false: function() {
|
||||
return this.get('value') === '';
|
||||
return this.get('value') === '' || this._super();
|
||||
},
|
||||
focus: function() {
|
||||
this.delay_focus(this.$element.find('input:first'));
|
||||
@@ -2088,7 +2115,7 @@ instance.web.form.FieldDatetime = instance.web.form.AbstractField.extend(_.exten
|
||||
return true;
|
||||
},
|
||||
is_false: function() {
|
||||
return this.get('value') === '';
|
||||
return this.get('value') === '' || this._super();
|
||||
},
|
||||
focus: function() {
|
||||
if (this.datewidget && this.datewidget.$input)
|
||||
@@ -2138,7 +2165,7 @@ instance.web.form.FieldText = instance.web.form.AbstractField.extend(_.extend({}
|
||||
return true;
|
||||
},
|
||||
is_false: function() {
|
||||
return this.get('value') === '';
|
||||
return this.get('value') === '' || this._super();
|
||||
},
|
||||
focus: function($element) {
|
||||
this.delay_focus(this.$textarea);
|
||||
@@ -3267,6 +3294,9 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({
|
||||
self.reload_content();
|
||||
this.is_setted.resolve();
|
||||
},
|
||||
get_value: function() {
|
||||
return [commands.replace_with(this.get('value'))];
|
||||
},
|
||||
load_view: function() {
|
||||
var self = this;
|
||||
this.list_view = new instance.web.form.Many2ManyListView(this, this.dataset, false, {
|
||||
@@ -3296,7 +3326,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({
|
||||
});
|
||||
},
|
||||
dataset_changed: function() {
|
||||
this.set({'value': [commands.replace_with(this.dataset.ids)]});
|
||||
this.set({'value': this.dataset.ids});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -3751,7 +3781,8 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
|
||||
self.view_list = new instance.web.form.SelectCreateListView(self,
|
||||
self.dataset, false,
|
||||
_.extend({'deletable': false,
|
||||
'selectable': !self.options.disable_multiple_selection
|
||||
'selectable': !self.options.disable_multiple_selection,
|
||||
'read_only': true,
|
||||
}, self.options.list_view_options || {}));
|
||||
self.view_list.popup = self;
|
||||
self.view_list.appendTo($(".oe-select-create-popup-view-list", self.$element)).pipe(function() {
|
||||
|
||||
@@ -21,6 +21,9 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
|
||||
// whether the view rows can be reordered (via vertical drag & drop)
|
||||
'reorderable': true,
|
||||
'action_buttons': true,
|
||||
// if true, the view can't be editable, ignoring the view's and the context's
|
||||
// instructions
|
||||
'read_only': false,
|
||||
},
|
||||
/**
|
||||
* Core class for list-type displays.
|
||||
@@ -339,6 +342,8 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
|
||||
this.sidebar = new instance.web.Sidebar(this);
|
||||
this.sidebar.appendTo(this.options.$sidebar);
|
||||
this.sidebar.add_items('other', [
|
||||
{ label: _t("Import"), callback: this.on_sidebar_import },
|
||||
{ label: _t("Export"), callback: this.on_sidebar_export },
|
||||
{ label: _t('Delete'), callback: this.do_delete_selected },
|
||||
]);
|
||||
this.sidebar.add_toolbar(this.fields_view.toolbar);
|
||||
|
||||
@@ -54,8 +54,7 @@ openerp.web.list_editable = function (instance) {
|
||||
// view' @editable is handled separately as we have not yet
|
||||
// fetched and processed the view at this point.
|
||||
this.options.editable = (
|
||||
(force && "bottom")
|
||||
|| this.defaults.editable);
|
||||
! this.options.read_only && ((force && "bottom") || this.defaults.editable));
|
||||
},
|
||||
/**
|
||||
* Replace do_search to handle editability process
|
||||
@@ -79,7 +78,7 @@ openerp.web.list_editable = function (instance) {
|
||||
},
|
||||
on_loaded: function (data, grouped) {
|
||||
// tree/@editable takes priority on everything else if present.
|
||||
this.options.editable = data.arch.attrs.editable || this.options.editable;
|
||||
this.options.editable = ! this.options.read_only && (data.arch.attrs.editable || this.options.editable);
|
||||
return this._super(data, grouped);
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -267,7 +267,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
|
||||
* @param {Boolean} [no_store=false] don't store the view being switched to on the switch stack
|
||||
* @returns {jQuery.Deferred} new view loading promise
|
||||
*/
|
||||
on_mode_switch: function(view_type, no_store) {
|
||||
on_mode_switch: function(view_type, no_store, view_options) {
|
||||
var self = this;
|
||||
var view = this.views[view_type];
|
||||
var view_promise;
|
||||
@@ -330,7 +330,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
|
||||
var controller = self.views[view_name].controller;
|
||||
if (controller) {
|
||||
if (view_name === view_type) {
|
||||
controller.do_show();
|
||||
controller.do_show(view_options || {});
|
||||
} else {
|
||||
controller.do_hide();
|
||||
}
|
||||
@@ -347,8 +347,8 @@ instance.web.ViewManager = instance.web.Widget.extend({
|
||||
* to be extended by child classes to change the default behavior, which simply
|
||||
* consist to switch to the asked view.
|
||||
*/
|
||||
switch_view: function(view_type, no_store) {
|
||||
return this.on_mode_switch(view_type, no_store);
|
||||
switch_view: function(view_type, no_store, options) {
|
||||
return this.on_mode_switch(view_type, no_store, options);
|
||||
},
|
||||
/**
|
||||
* Returns to the view preceding the caller view in this manager's
|
||||
@@ -651,10 +651,10 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
|
||||
}, action || {});
|
||||
this.do_action(action);
|
||||
},
|
||||
on_mode_switch: function (view_type, no_store) {
|
||||
on_mode_switch: function (view_type, no_store, options) {
|
||||
var self = this;
|
||||
|
||||
return $.when(this._super(view_type, no_store)).then(function () {
|
||||
return $.when(this._super.apply(this, arguments)).then(function () {
|
||||
var controller = self.views[self.active_view].controller,
|
||||
fvg = controller.fields_view,
|
||||
view_id = (fvg && fvg.view_id) || '--';
|
||||
@@ -706,11 +706,8 @@ instance.web.Sidebar = instance.web.Widget.extend({
|
||||
this.items = {
|
||||
'print' : [],
|
||||
'files' : [],
|
||||
'other' : [
|
||||
{ label: _t("Import"), callback: view.on_sidebar_import },
|
||||
{ label: _t("Export"), callback: view.on_sidebar_export }
|
||||
]
|
||||
}
|
||||
'other' : []
|
||||
};
|
||||
if (this.session.uid === 1) {
|
||||
var item = { label: _t("Translate"), callback: view.on_sidebar_translate, title: _t("Technical translation") };
|
||||
this.items.other.push(item);
|
||||
@@ -746,6 +743,11 @@ instance.web.Sidebar = instance.web.Widget.extend({
|
||||
var self = this;
|
||||
self.$element.html(QWeb.render('Sidebar', {widget: self}));
|
||||
this.$element.find('ul').hide();
|
||||
|
||||
// Hides Sidebar sections when item list is empty
|
||||
this.$('.oe_form_dropdown_section').each(function() {
|
||||
$(this).toggle(!!$(this).find('li').length);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* For each item added to the section:
|
||||
|
||||
@@ -424,7 +424,7 @@
|
||||
<td>
|
||||
<ul class="oe_view_manager_switch oe_button_group oe_right">
|
||||
<t t-if="widget.views_src.length > 2" t-foreach="widget.views_src" t-as="view">
|
||||
<li t-if="view.view_type != 'form'" class="oe_e"><a 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">
|
||||
<li t-if="view.view_type != 'form'" class="oe_e"><a t-attf-class="oe_vm_switch_#{view.view_type}" t-att-data-view-type="view.view_type" t-att-title="_t('Switch to ') + (view.label || view.view_type)">
|
||||
</a></li>
|
||||
</t>
|
||||
</ul>
|
||||
|
||||
@@ -109,11 +109,23 @@ instance.web_kanban.KanbanView = instance.web.View.extend({
|
||||
}
|
||||
},
|
||||
transform_qweb_template: function(node) {
|
||||
var qweb_prefix = QWeb.prefix;
|
||||
var qweb_add_if = function(node, condition) {
|
||||
if (node.attrs[QWeb.prefix + '-if']) {
|
||||
condition = _.str.sprintf("(%s) and (%s)", node.attrs[QWeb.prefix + '-if'], condition);
|
||||
}
|
||||
node.attrs[QWeb.prefix + '-if'] = condition;
|
||||
};
|
||||
// Process modifiers
|
||||
if (node.tag && node.attrs.modifiers) {
|
||||
var modifiers = JSON.parse(node.attrs.modifiers || '{}');
|
||||
if (modifiers.invisible) {
|
||||
qweb_add_if(node, _.str.sprintf("!kanban_compute_domain(%s)", JSON.stringify(modifiers.invisible)));
|
||||
}
|
||||
}
|
||||
switch (node.tag) {
|
||||
case 'field':
|
||||
node.tag = qweb_prefix;
|
||||
node.attrs[qweb_prefix + '-esc'] = 'record.' + node.attrs['name'] + '.value';
|
||||
node.tag = QWeb.prefix;
|
||||
node.attrs[QWeb.prefix + '-esc'] = 'record.' + node.attrs['name'] + '.value';
|
||||
this.extract_aggregates(node);
|
||||
break;
|
||||
case 'button':
|
||||
@@ -126,18 +138,6 @@ instance.web_kanban.KanbanView = instance.web.View.extend({
|
||||
delete(node.attrs[k]);
|
||||
}
|
||||
});
|
||||
if (node.attrs['data-states']) {
|
||||
var states = _.map(node.attrs['data-states'].split(','), function(state) {
|
||||
return "record.state.raw_value == '" + _.str.trim(state) + "'";
|
||||
});
|
||||
node.attrs[qweb_prefix + '-if'] = states.join(' or ');
|
||||
}
|
||||
if (node.attrs['data-kanban_states']) {
|
||||
var states = _.map(node.attrs['data-kanban_states'].split(','), function(state) {
|
||||
return "record.kanban_state.raw_value == '" + _.str.trim(state) + "'";
|
||||
});
|
||||
node.attrs[qweb_prefix + '-if'] = states.join(' or ');
|
||||
}
|
||||
if (node.attrs['data-string']) {
|
||||
node.attrs.title = node.attrs['data-string'];
|
||||
}
|
||||
@@ -325,7 +325,7 @@ instance.web_kanban.KanbanView = instance.web.View.extend({
|
||||
},
|
||||
open_record: function(id) {
|
||||
if (this.dataset.select_id(id)) {
|
||||
this.do_switch_view('form');
|
||||
this.do_switch_view('form', null, { editable: true });
|
||||
} else {
|
||||
this.do_warn("Kanban: could not find id#" + id);
|
||||
}
|
||||
@@ -530,7 +530,14 @@ instance.web_kanban.KanbanRecord = instance.web.OldWidget.extend({
|
||||
this.state = this.view.state.records[this.id];
|
||||
},
|
||||
set_record: function(record) {
|
||||
var self = this;
|
||||
this.id = record.id;
|
||||
this.values = {};
|
||||
_.each(record, function(v, k) {
|
||||
self.values[k] = {
|
||||
value: v
|
||||
};
|
||||
});
|
||||
this.record = this.transform_record(record);
|
||||
},
|
||||
start: function() {
|
||||
@@ -751,6 +758,9 @@ instance.web_kanban.KanbanRecord = instance.web.OldWidget.extend({
|
||||
} else {
|
||||
return s.substr(0, size) + '...';
|
||||
}
|
||||
},
|
||||
kanban_compute_domain: function(domain) {
|
||||
return instance.web.form.compute_domain(domain, this.values);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user