summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/css/base.css9
-rw-r--r--addons/web/static/src/css/base.sass5
-rw-r--r--addons/web/static/src/img/back-enable.jpgbin0 -> 28373 bytes
-rw-r--r--addons/web/static/src/js/chrome.js20
-rw-r--r--addons/web/static/src/js/search.js107
-rw-r--r--addons/web/static/src/js/view_form.js41
-rw-r--r--addons/web/static/src/js/view_list.js4
-rw-r--r--addons/web/static/src/js/view_list_editable.js2
-rw-r--r--addons/web/static/src/js/views.js75
-rw-r--r--addons/web/static/src/xml/base.xml3
10 files changed, 199 insertions, 67 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index 6cfee50d6a4..be26b7edd70 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -1,4 +1,4 @@
-@charset "UTF-8";
+@charset "utf-8";
@font-face {
font-family: "mnmliconsRegular";
src: url("/web/static/src/font/mnmliconsv21-webfont.eot") format("eot");
@@ -1415,7 +1415,13 @@
display: inline-block;
overflow: hidden;
}
+.openerp .oe_view_manager {
+ display: table;
+ height: inherit;
+ width: 100%;
+}
.openerp .oe_view_manager .oe_view_manager_body {
+ display: table-row;
height: inherit;
}
.openerp .oe_view_manager .oe_view_manager_view_kanban {
@@ -3089,7 +3095,6 @@
}
.kitten-mode-activated {
- background-image: url(http://placekitten.com/g/1365/769);
background-size: cover;
background-attachment: fixed;
}
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index b4665808caf..b308b825775 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -1137,7 +1137,11 @@ $sheet-padding: 16px
// }}}
// ViewManager common {{{
.oe_view_manager
+ display: table
+ height: inherit
+ width: 100%
.oe_view_manager_body
+ display: table-row
height: inherit
.oe_view_manager_view_kanban
height: inherit
@@ -2436,7 +2440,6 @@ $sheet-padding: 16px
// }}}
// Kitten Mode {{{
.kitten-mode-activated
- background-image: url(http://placekitten.com/g/1365/769)
background-size: cover
background-attachment: fixed
>*
diff --git a/addons/web/static/src/img/back-enable.jpg b/addons/web/static/src/img/back-enable.jpg
new file mode 100644
index 00000000000..79a7098f6da
--- /dev/null
+++ b/addons/web/static/src/img/back-enable.jpg
Binary files differ
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index 86d0a20ed20..6051dcdb633 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -1100,6 +1100,9 @@ instance.web.UserMenu = instance.web.Widget.extend({
};
this.update_promise = this.update_promise.then(fct, fct);
},
+ on_menu_help: function() {
+ window.open('http://help.openerp.com', '_blank');
+ },
on_menu_logout: function() {
this.trigger('user_logout');
},
@@ -1213,6 +1216,7 @@ instance.web.WebClient = instance.web.Client.extend({
return $.when(this._super()).then(function() {
if (jQuery.param !== undefined && jQuery.deparam(jQuery.param.querystring()).kitten !== undefined) {
$("body").addClass("kitten-mode-activated");
+ $("body").css("background-image", "url(" + instance.session.origin + "/web/static/src/img/back-enable.jpg" + ")");
if ($.blockUI) {
$.blockUI.defaults.message = '<img src="http://www.amigrave.com/kitten.gif">';
}
@@ -1396,8 +1400,9 @@ instance.web.WebClient = instance.web.Client.extend({
},
on_hashchange: function(event) {
var self = this;
- var state = event.getState(true);
- if (!_.isEqual(this._current_state, state)) {
+ var stringstate = event.getState(false);
+ if (!_.isEqual(this._current_state, stringstate)) {
+ var state = event.getState(true);
if(!state.action && state.menu_id) {
self.menu.has_been_loaded.done(function() {
self.menu.do_reload().done(function() {
@@ -1409,13 +1414,13 @@ instance.web.WebClient = instance.web.Client.extend({
this.action_manager.do_load_state(state, !!this._current_state);
}
}
- this._current_state = state;
+ this._current_state = stringstate;
},
do_push_state: function(state) {
this.set_title(state.title);
delete state.title;
var url = '#' + $.param(state);
- this._current_state = _.clone(state);
+ this._current_state = $.deparam($.param(state), false); // stringify all values
$.bbq.pushState(url);
this.trigger('state_pushed', state);
},
@@ -1425,9 +1430,10 @@ instance.web.WebClient = instance.web.Client.extend({
.then(function (result) {
return self.action_mutex.exec(function() {
if (options.needaction) {
- result.context = new instance.web.CompoundContext(
- result.context,
- {search_default_message_unread: true});
+ result.context = new instance.web.CompoundContext(result.context, {
+ search_default_message_unread: true,
+ search_disable_custom_filters: true,
+ });
}
var completed = $.Deferred();
$.when(self.action_manager.do_action(result, {
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index 12acf4039f4..32f1d31d795 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -690,7 +690,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
return filter.user_id && filter.is_default;
});
if (personal_filter) {
- this.custom_filters.enable_filter(personal_filter, true);
+ this.custom_filters.toggle_filter(personal_filter, true);
return;
}
@@ -698,7 +698,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
return !filter.user_id && filter.is_default;
});
if (global_filter) {
- this.custom_filters.enable_filter(global_filter, true);
+ this.custom_filters.toggle_filter(global_filter, true);
return;
}
}
@@ -1541,6 +1541,9 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
})
.on('reset', this.proxy('clear_selection'));
this.$el.on('submit', 'form', this.proxy('save_current'));
+ this.$el.on('click', 'input[type=checkbox]', function() {
+ $(this).siblings('input[type=checkbox]').prop('checked', false);
+ });
this.$el.on('click', 'h4', function () {
self.$el.toggleClass('oe_opened');
});
@@ -1591,6 +1594,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
get_groupby: function () { return [filter.context]; },
get_domain: function () { return filter.domain; }
},
+ _id: filter['id'],
is_custom_filter: true,
values: [{label: filter.name, value: null}]
};
@@ -1632,10 +1636,18 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
}
$filter.unbind('click').click(function () {
- self.enable_filter(filter);
+ self.toggle_filter(filter);
});
},
- enable_filter: function (filter, preventSearch) {
+ toggle_filter: function (filter, preventSearch) {
+ var current = this.view.query.find(function (facet) {
+ return facet.get('_id') === filter.id;
+ });
+ if (current) {
+ this.view.query.remove(current);
+ this.$filters[this.key_for(filter)].removeClass('oe_selected');
+ return;
+ }
this.view.query.reset([this.facet_for(filter)], {
preventSearch: preventSearch || false});
this.$filters[this.key_for(filter)].addClass('oe_selected');
@@ -1800,6 +1812,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
template: 'SearchView.extended_search.proposition',
events: {
'change .searchview_extended_prop_field': 'changed',
+ 'change .searchview_extended_prop_op': 'operator_changed',
'click .searchview_extended_delete_prop': function (e) {
e.stopPropagation();
this.getParent().remove_proposition(this);
@@ -1831,6 +1844,17 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
this.select_field(_.detect(this.fields, function(x) {return x.name == nval;}));
}
},
+ operator_changed: function (e) {
+ var $value = this.$('.searchview_extended_prop_value');
+ switch ($(e.target).val()) {
+ case '∃':
+ case '∄':
+ $value.hide();
+ break;
+ default:
+ $value.show();
+ }
+ },
/**
* Selects the provided field object
*
@@ -1859,7 +1883,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
.text(String(operator.text))
.appendTo(self.$('.searchview_extended_prop_op'));
});
- var $value_loc = this.$('.searchview_extended_prop_value').empty();
+ var $value_loc = this.$('.searchview_extended_prop_value').show().empty();
this.value.appendTo($value_loc);
},
@@ -1867,19 +1891,12 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
if ( this.attrs.selected == null)
return null;
var field = this.attrs.selected;
- var op = this.$('.searchview_extended_prop_op')[0];
- var operator = op.options[op.selectedIndex];
+ var op_select = this.$('.searchview_extended_prop_op')[0];
+ var operator = op_select.options[op_select.selectedIndex];
+
return {
- label: _.str.sprintf(_t('%(field)s %(operator)s "%(value)s"'), {
- field: field.string,
- // According to spec, HTMLOptionElement#label should return
- // HTMLOptionElement#text when not defined/empty, but it does
- // not in older Webkit (between Safari 5.1.5 and Chrome 17) and
- // Gecko (pre Firefox 7) browsers, so we need a manual fallback
- // for those
- operator: operator.label || operator.text,
- value: this.value}),
- value: [field.name, operator.value, this.value.get_value()]
+ label: this.value.get_label(field, operator),
+ value: this.value.get_domain(field, operator),
};
}
});
@@ -1889,6 +1906,37 @@ instance.web.search.ExtendedSearchProposition.Field = instance.web.Widget.extend
this._super(parent);
this.field = field;
},
+ get_label: function (field, operator) {
+ var format;
+ switch (operator.value) {
+ case '∃': case '∄': format = _t('%(field)s %(operator)s'); break;
+ default: format = _t('%(field)s %(operator)s "%(value)s"'); break;
+ }
+ return this.format_label(format, field, operator);
+ },
+ format_label: function (format, field, operator) {
+ return _.str.sprintf(format, {
+ field: field.string,
+ // According to spec, HTMLOptionElement#label should return
+ // HTMLOptionElement#text when not defined/empty, but it does
+ // not in older Webkit (between Safari 5.1.5 and Chrome 17) and
+ // Gecko (pre Firefox 7) browsers, so we need a manual fallback
+ // for those
+ operator: operator.label || operator.text,
+ value: this
+ });
+ },
+ get_domain: function (field, operator) {
+ switch (operator.value) {
+ case '∃': return this.make_domain(field.name, '!=', false);
+ case '∄': return this.make_domain(field.name, '=', false);
+ default: return this.make_domain(
+ field.name, operator.value, this.get_value());
+ }
+ },
+ make_domain: function (field, operator, value) {
+ return [field, operator, value];
+ },
/**
* Returns a human-readable version of the value, in case the "logical"
* and the "semantic" values of a field differ (as for selection fields,
@@ -1908,7 +1956,9 @@ instance.web.search.ExtendedSearchProposition.Char = instance.web.search.Extende
{value: "ilike", text: _lt("contains")},
{value: "not ilike", text: _lt("doesn't contain")},
{value: "=", text: _lt("is equal to")},
- {value: "!=", text: _lt("is not equal to")}
+ {value: "!=", text: _lt("is not equal to")},
+ {value: "∃", text: _lt("is set")},
+ {value: "∄", text: _lt("is not set")}
],
get_value: function() {
return this.$el.val();
@@ -1922,7 +1972,9 @@ instance.web.search.ExtendedSearchProposition.DateTime = instance.web.search.Ext
{value: ">", text: _lt("greater than")},
{value: "<", text: _lt("less than")},
{value: ">=", text: _lt("greater or equal than")},
- {value: "<=", text: _lt("less or equal than")}
+ {value: "<=", text: _lt("less or equal than")},
+ {value: "∃", text: _lt("is set")},
+ {value: "∄", text: _lt("is not set")}
],
/**
* Date widgets live in view_form which is not yet loaded when this is
@@ -1956,7 +2008,9 @@ instance.web.search.ExtendedSearchProposition.Integer = instance.web.search.Exte
{value: ">", text: _lt("greater than")},
{value: "<", text: _lt("less than")},
{value: ">=", text: _lt("greater or equal than")},
- {value: "<=", text: _lt("less or equal than")}
+ {value: "<=", text: _lt("less or equal than")},
+ {value: "∃", text: _lt("is set")},
+ {value: "∄", text: _lt("is not set")}
],
toString: function () {
return this.$el.val();
@@ -1981,7 +2035,9 @@ instance.web.search.ExtendedSearchProposition.Float = instance.web.search.Extend
{value: ">", text: _lt("greater than")},
{value: "<", text: _lt("less than")},
{value: ">=", text: _lt("greater or equal than")},
- {value: "<=", text: _lt("less or equal than")}
+ {value: "<=", text: _lt("less or equal than")},
+ {value: "∃", text: _lt("is set")},
+ {value: "∄", text: _lt("is not set")}
],
toString: function () {
return this.$el.val();
@@ -1999,7 +2055,9 @@ instance.web.search.ExtendedSearchProposition.Selection = instance.web.search.Ex
template: 'SearchView.extended_search.proposition.selection',
operators: [
{value: "=", text: _lt("is")},
- {value: "!=", text: _lt("is not")}
+ {value: "!=", text: _lt("is not")},
+ {value: "∃", text: _lt("is set")},
+ {value: "∄", text: _lt("is not set")}
],
toString: function () {
var select = this.$el[0];
@@ -2016,7 +2074,10 @@ instance.web.search.ExtendedSearchProposition.Boolean = instance.web.search.Exte
{value: "=", text: _lt("is true")},
{value: "!=", text: _lt("is false")}
],
- toString: function () { return ''; },
+ get_label: function (field, operator) {
+ return this.format_label(
+ _t('%(field)s %(operator)s'), field, operator);
+ },
get_value: function() {
return true;
}
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 4880b3882ff..a023dd54174 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -251,9 +251,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
this.dataset.ids.push(state.id);
}
this.dataset.select_id(state.id);
- if (warm) {
- this.do_show();
- }
+ this.do_show({ reload: warm });
}
},
/**
@@ -511,9 +509,13 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
var on_change = widget.node.attrs.on_change;
if (on_change) {
var change_spec = self.parse_on_change(on_change, widget);
- var id = [self.datarecord.id == null ? [] : [self.datarecord.id]];
+ var ids = [];
+ if (self.datarecord.id && !instance.web.BufferedDataSet.virtual_id_regex.test(self.datarecord.id)) {
+ // In case of a o2m virtual id, we should pass an empty ids list
+ ids.push(self.datarecord.id);
+ }
def = new instance.web.Model(self.dataset.model).call(
- change_spec.method, id.concat(change_spec.args));
+ change_spec.method, [ids].concat(change_spec.args));
} else {
def = $.when({});
}
@@ -2376,6 +2378,7 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({
type_of_date: "datetime",
events: {
'change .oe_datepicker_master': 'change_datetime',
+ 'dragstart img.oe_datepicker_trigger': function () { return false; },
},
init: function(parent) {
this._super(parent);
@@ -2957,7 +2960,9 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
case $.ui.keyCode.DOWN:
e.stopPropagation();
}
- }
+ },
+ 'dragstart .oe_m2o_drop_down_button img': function () { return false; },
+ 'dragstart .oe_m2o_cm_button': function () { return false; }
},
init: function(field_manager, node) {
this._super(field_manager, node);
@@ -4450,6 +4455,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
* options:
* -readonly: only applicable when not in creation mode, default to false
* - alternative_form_view
+ * - view_id
* - write_function
* - read_function
* - create_function
@@ -4516,7 +4522,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
_.extend(options, {
$buttons: this.$buttonpane,
});
- this.view_form = new instance.web.FormView(this, this.dataset, false, options);
+ this.view_form = new instance.web.FormView(this, this.dataset, this.options.view_id || false, options);
if (this.options.alternative_form_view) {
this.view_form.set_embedded_view(this.options.alternative_form_view);
}
@@ -4545,6 +4551,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
});
var $cbutton = self.$buttonpane.find(".oe_abstractformpopup-form-close");
$cbutton.click(function() {
+ self.view_form.trigger('on_button_cancel');
self.check_exit();
});
self.view_form.do_show();
@@ -5216,6 +5223,8 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
this.options.clickable = this.options.clickable || (this.node.attrs || {}).clickable || false;
this.options.visible = this.options.visible || (this.node.attrs || {}).statusbar_visible || false;
this.set({value: false});
+ this.field_manager.on("view_content_has_changed", this, this.render_value);
+ this.selection_mutex = new $.Mutex();
},
start: function() {
if (this.options.clickable) {
@@ -5234,14 +5243,16 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
},
render_value: function() {
var self = this;
- self.get_selection().done(function() {
- var content = QWeb.render("FieldStatus.content", {widget: self});
- self.$el.html(content);
- var colors = JSON.parse((self.node.attrs || {}).statusbar_colors || "{}");
- var color = colors[self.get('value')];
- if (color) {
- self.$("oe_active").css("color", color);
- }
+ self.selection_mutex.exec(function() {
+ return self.get_selection().done(function() {
+ var content = QWeb.render("FieldStatus.content", {widget: self});
+ self.$el.html(content);
+ var colors = JSON.parse((self.node.attrs || {}).statusbar_colors || "{}");
+ var color = colors[self.get('value')];
+ if (color) {
+ self.$("oe_active").css("color", color);
+ }
+ });
});
},
/** Get the selection and render it
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index fbbfabcacca..27e2c88daaf 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -1186,7 +1186,7 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web.
}
});
instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.web.ListView.Groups# */{
- passtrough_events: 'action deleted row_link',
+ passthrough_events: 'action deleted row_link',
/**
* Grouped display for the ListView. Handles basic DOM events and interacts
* with the :js:class:`~DataGroup` bound to it.
@@ -1406,7 +1406,7 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
// can have selections spanning multiple links
var selection = self.get_selection();
$this.trigger(e, [selection.ids, selection.records]);
- }).bind(this.passtrough_events, function (e) {
+ }).bind(this.passthrough_events, function (e) {
// additional positional parameters are provided to trigger as an
// Array, following the event type or event object, but are
// provided to the .bind event handler as *args.
diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js
index efc442de2a9..6be83e7af52 100644
--- a/addons/web/static/src/js/view_list_editable.js
+++ b/addons/web/static/src/js/view_list_editable.js
@@ -795,7 +795,7 @@ openerp.web.list_editable = function (instance) {
});
instance.web.ListView.Groups.include(/** @lends instance.web.ListView.Groups# */{
- passtrough_events: instance.web.ListView.Groups.prototype.passtrough_events + " edit saved",
+ passthrough_events: instance.web.ListView.Groups.prototype.passthrough_events + " edit saved",
get_row_for: function (record) {
return _(this.children).chain()
.invoke('get_row_for', record)
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index 9fd49367171..31f3df4a746 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -190,6 +190,18 @@ instance.web.ActionManager = instance.web.Widget.extend({
});
state = _.extend(params || {}, state);
}
+ if (this.inner_action.context) {
+ var active_id = this.inner_action.context.active_id;
+ if (active_id) {
+ state["active_id"] = active_id;
+ }
+ var active_ids = this.inner_action.context.active_ids;
+ if (active_ids && !(active_ids.length === 1 && active_ids[0] === active_id)) {
+ // We don't push active_ids if it's a single element array containing the active_id
+ // This makes the url shorter in most cases.
+ state["active_ids"] = this.inner_action.context.active_ids.join(',');
+ }
+ }
}
if(!this.dialog) {
this.getParent().do_push_state(state);
@@ -212,8 +224,22 @@ instance.web.ActionManager = instance.web.Widget.extend({
} else {
var run_action = (!this.inner_widget || !this.inner_widget.action) || this.inner_widget.action.id !== state.action;
if (run_action) {
+ var add_context = {};
+ if (state.active_id) {
+ add_context.active_id = state.active_id;
+ }
+ if (state.active_ids) {
+ // The jQuery BBQ plugin does some parsing on values that are valid integers.
+ // It means that if there's only one item, it will do parseInt() on it,
+ // otherwise it will keep the comma seperated list as string.
+ add_context.active_ids = state.active_ids.toString().split(',').map(function(id) {
+ return parseInt(id, 10) || id;
+ });
+ } else if (state.active_id) {
+ add_context.active_ids = [state.active_id];
+ }
this.null_action();
- action_loaded = this.do_action(state.action);
+ action_loaded = this.do_action(state.action, { additional_context: add_context });
$.when(action_loaded || null).done(function() {
instance.webclient.menu.has_been_loaded.done(function() {
if (self.inner_action && self.inner_action.id) {
@@ -249,12 +275,25 @@ instance.web.ActionManager = instance.web.Widget.extend({
}
});
},
+ /**
+ * Execute an OpenERP action
+ *
+ * @param {Number|String|Object} Can be either an action id, a client action or an action descriptor.
+ * @param {Object} [options]
+ * @param {Boolean} [options.clear_breadcrumbs=false] Clear the breadcrumbs history list
+ * @param {Function} [options.on_reverse_breadcrumb] Callback to be executed whenever an anterior breadcrumb item is clicked on.
+ * @param {Function} [options.on_close] Callback to be executed when the dialog is closed (only relevant for target=new actions)
+ * @param {Function} [options.action_menu_id] Manually set the menu id on the fly.
+ * @param {Object} [options.additional_context] Additional context to be merged with the action's context.
+ * @return {jQuery.Deferred} Action loaded
+ */
do_action: function(action, options) {
options = _.defaults(options || {}, {
clear_breadcrumbs: false,
on_reverse_breadcrumb: function() {},
on_close: function() {},
action_menu_id: null,
+ additional_context: {},
});
if (action === false) {
action = { type: 'ir.actions.act_window_close' };
@@ -269,9 +308,13 @@ instance.web.ActionManager = instance.web.Widget.extend({
}
// Ensure context & domain are evaluated and can be manipulated/used
- if (action.context) {
- action.context = instance.web.pyeval.eval(
- 'context', action.context);
+ var ncontext = new instance.web.CompoundContext(options.additional_context, action.context || {});
+ action.context = instance.web.pyeval.eval('context', ncontext);
+ if (action.context.active_id || action.context.active_ids) {
+ // Here we assume that when an `active_id` or `active_ids` is used
+ // in the context, we are in a `related` action, so we disable the
+ // searchview's default custom filters.
+ action.context.search_disable_custom_filters = true;
}
if (action.domain) {
action.domain = instance.web.pyeval.eval(
@@ -539,7 +582,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
_.each(_.keys(self.views), function(view_name) {
var controller = self.views[view_name].controller;
if (controller) {
- var container = self.$el.find(".oe_view_manager_view_" + view_name + ":first");
+ var container = self.$el.find("> .oe_view_manager_body > .oe_view_manager_view_" + view_name);
if (view_name === view_type) {
container.show();
controller.do_show(view_options || {});
@@ -582,7 +625,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
controller.on('switch_mode', self, this.switch_mode);
controller.on('previous_view', self, this.prev_view);
- var container = this.$el.find(".oe_view_manager_view_" + view_type);
+ var container = this.$el.find("> .oe_view_manager_body > .oe_view_manager_view_" + view_type);
var view_promise = controller.appendTo(container);
this.views[view_type].controller = controller;
this.views[view_type].deferred.resolve(view_type);
@@ -597,6 +640,12 @@ instance.web.ViewManager = instance.web.Widget.extend({
self.trigger("controller_inited",view_type,controller);
});
},
+ /**
+ * @returns {Number|Boolean} the view id of the given type, false if not found
+ */
+ get_view_id: function(view_type) {
+ return this.views[view_type] && this.views[view_type].view_id || false;
+ },
set_title: function(title) {
this.$el.find('.oe_view_title_text:first').text(title);
},
@@ -953,10 +1002,11 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
});
},
do_create_view: function(view_type) {
- var r = this._super.apply(this, arguments);
- var view = this.views[view_type].controller;
- view.set({ 'title': this.action.name });
- return r;
+ var self = this;
+ return this._super.apply(this, arguments).then(function() {
+ var view = self.views[view_type].controller;
+ view.set({ 'title': self.action.name });
+ });
},
get_action_manager: function() {
var cur = this;
@@ -1270,11 +1320,6 @@ instance.web.View = instance.web.Widget.extend({
active_ids: [record_id],
active_model: dataset.model
});
- if (("" + action.context).match(/\bactive_id\b/)) {
- // Special case: when the context is evaluted using
- // the active_id, we want to disable the custom filters.
- ncontext.add({ search_disable_custom_filters: true });
- }
}
ncontext.add(action.context || {});
action.context = ncontext;
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 7604814fe1d..d56e0906270 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -403,8 +403,9 @@
<img class="oe_topbar_avatar" t-att-data-default-src="_s + '/web/static/src/img/user_menu_avatar.png'"/>
<span class="oe_topbar_name"/>
<ul class="oe_dropdown_menu">
- <li><a href="#" data-menu="about">About OpenERP</a></li>
<li><a href="#" data-menu="settings">Preferences</a></li>
+ <li><a href="#" data-menu="about">About OpenERP</a></li>
+ <li><a href="#" data-menu="help">Help</a></li>
<li><a href="#" data-menu="logout">Log out</a></li>
</ul>
</span>