summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src/js/chrome')
-rw-r--r--addons/web/static/src/js/chrome/abstract_web_client.js13
-rw-r--r--addons/web/static/src/js/chrome/action_manager.js16
-rw-r--r--addons/web/static/src/js/chrome/action_manager_act_window.js53
-rw-r--r--addons/web/static/src/js/chrome/control_panel.js4
-rw-r--r--addons/web/static/src/js/chrome/search_menus.js31
5 files changed, 102 insertions, 15 deletions
diff --git a/addons/web/static/src/js/chrome/abstract_web_client.js b/addons/web/static/src/js/chrome/abstract_web_client.js
index b4b192c1ea9..9fe38adbde6 100644
--- a/addons/web/static/src/js/chrome/abstract_web_client.js
+++ b/addons/web/static/src/js/chrome/abstract_web_client.js
@@ -68,6 +68,7 @@ var AbstractWebClient = Widget.extend(ServiceProviderMixin, {
.load_filters(event.data.dataset, event.data.action_id)
.then(event.data.on_success);
},
+ create_filter: '_onCreateFilter',
push_state: '_onPushState',
show_effect: '_onShowEffect',
// session
@@ -338,6 +339,18 @@ var AbstractWebClient = Widget.extend(ServiceProviderMixin, {
//--------------------------------------------------------------------------
/**
+ * @private
+ * @param {OdooEvent} e
+ * @param {Object} e.data.filter the filter description
+ * @param {function} e.data.on_success called when the RPC succeeds with its
+ * returned value as argument
+ */
+ _onCreateFilter: function (e) {
+ data_manager
+ .create_filter(e.data.filter)
+ .then(e.data.on_success);
+ },
+ /**
* Displays a warning in a dialog of with the NotificationManager
*
* @private
diff --git a/addons/web/static/src/js/chrome/action_manager.js b/addons/web/static/src/js/chrome/action_manager.js
index e213b55189d..1e9c52238bc 100644
--- a/addons/web/static/src/js/chrome/action_manager.js
+++ b/addons/web/static/src/js/chrome/action_manager.js
@@ -136,9 +136,10 @@ var ActionManager = Widget.extend({
* is useful when we come from a loadState())
* @param {boolean} [options.replace_last_action=false] set to true to
* replace last part of the breadcrumbs with the action
- * @return {Deferred} resolved when the action is loaded and appended to the
- * DOM ; rejected if the action can't be executed (e.g. if doAction has
- * been called to execute another action before this one was complete).
+ * @return {$.Deferred<Object>} resolved with the action when the action is
+ * loaded and appended to the DOM ; rejected if the action can't be
+ * executed (e.g. if doAction has been called to execute another action
+ * before this one was complete).
*/
doAction: function (action, options) {
var self = this;
@@ -175,7 +176,9 @@ var ActionManager = Widget.extend({
self._preprocessAction(action, options);
- return self._handleAction(action, options);
+ return self._handleAction(action, options).then(function () {
+ return action;
+ });
});
},
/**
@@ -349,6 +352,11 @@ var ActionManager = Widget.extend({
// toggle the fullscreen mode for actions in target='fullscreen'
self._toggleFullscreen();
+ // now that the action has been executed, force its 'pushState'
+ // flag to 'true', as we don't want to prevent its controller
+ // from pushing its state if it changes in the future
+ action.pushState = true;
+
return action;
})
.fail(function () {
diff --git a/addons/web/static/src/js/chrome/action_manager_act_window.js b/addons/web/static/src/js/chrome/action_manager_act_window.js
index 9cfa99a9e7d..dfb512900e8 100644
--- a/addons/web/static/src/js/chrome/action_manager_act_window.js
+++ b/addons/web/static/src/js/chrome/action_manager_act_window.js
@@ -21,6 +21,7 @@ ActionManager.include({
custom_events: _.extend({}, ActionManager.prototype.custom_events, {
env_updated: '_onEnvUpdated',
execute_action: '_onExecuteAction',
+ get_controller_context: '_onGetControllerContext',
search: '_onSearch',
switch_view: '_onSwitchView',
}),
@@ -254,18 +255,26 @@ ActionManager.include({
action.env = self._generateActionEnv(action, options);
action.controllers = {};
- // select the first view to display
- var lazyLoadFirstView = false;
+ // select the first view to display, and optionally the main view
+ // which will be lazyloaded
var firstView = options.viewType && _.findWhere(views, {type: options.viewType});
+ var mainView;
if (firstView) {
if (!firstView.multiRecord && views[0].multiRecord) {
- lazyLoadFirstView = true;
+ mainView = views[0];
}
} else {
firstView = views[0];
}
- if (config.device.isMobile && !firstView.isMobileFriendly) {
- firstView = _.findWhere(action.views, {isMobileFriendly: true}) || firstView;
+
+ // use mobile-friendly view by default in mobile, if possible
+ if (config.device.isMobile) {
+ if (!firstView.isMobileFriendly) {
+ firstView = self._findMobileView(views, firstView.multiRecord) || firstView;
+ }
+ if (mainView && !mainView.isMobileFriendly) {
+ mainView = self._findMobileView(views, mainView.multiRecord) || mainView;
+ }
}
var def;
@@ -279,8 +288,8 @@ ActionManager.include({
return $.when(def).then(function () {
var defs = [];
defs.push(self._createViewController(action, firstView.type));
- if (lazyLoadFirstView) {
- defs.push(self._createViewController(action, views[0].type, {}, {lazy: true}));
+ if (mainView) {
+ defs.push(self._createViewController(action, mainView.type, {}, {lazy: true}));
}
return $.when.apply($, defs);
}).then(function (controller, lazyLoadedController) {
@@ -297,6 +306,22 @@ ActionManager.include({
});
},
/**
+ * Helper function to find the first mobile-friendly view, if any.
+ *
+ * @private
+ * @param {Array} views an array of views
+ * @param {boolean} multiRecord set to true iff we search for a multiRecord
+ * view
+ * @returns {Object|undefined} a mobile-friendly view of the requested
+ * multiRecord type, undefined if there is no such view
+ */
+ _findMobileView: function (views, multiRecord) {
+ return _.findWhere(views, {
+ isMobileFriendly: true,
+ multiRecord: multiRecord,
+ });
+ },
+ /**
* Generates the initial environment of a given action, which is a dict
* containing information like the model name, the domain, the context...
* That information is shared between the controllers of the corresponding
@@ -716,6 +741,20 @@ ActionManager.include({
});
},
/**
+ * Handles a context request: provides to the caller the context of the
+ * current controller.
+ *
+ * @private
+ * @param {OdooEvent} ev
+ * @param {function} ev.data.callback used to send the requested context
+ */
+ _onGetControllerContext: function (ev) {
+ ev.stopPropagation();
+ var currentController = this.getCurrentController();
+ var context = currentController && currentController.widget.getContext();
+ ev.data.callback(context || {});
+ },
+ /**
* Called when there is a change in the search view, so the current action's
* environment needs to be updated with the new domain, context and groupby.
*
diff --git a/addons/web/static/src/js/chrome/control_panel.js b/addons/web/static/src/js/chrome/control_panel.js
index 16b22761581..03b9e756bb7 100644
--- a/addons/web/static/src/js/chrome/control_panel.js
+++ b/addons/web/static/src/js/chrome/control_panel.js
@@ -154,7 +154,9 @@ var ControlPanel = Widget.extend({
this._attach_content(new_cp_content);
// Update the searchview and switch buttons
- this._update_search_view(status.searchview, status.search_view_hidden, status.groupable);
+ if (status.searchview || options.clear) {
+ this._update_search_view(status.searchview, status.search_view_hidden, status.groupable);
+ }
if (status.active_view_selector) {
this._update_switch_buttons(status.active_view_selector);
}
diff --git a/addons/web/static/src/js/chrome/search_menus.js b/addons/web/static/src/js/chrome/search_menus.js
index 38f2bb7374c..d33cdce6500 100644
--- a/addons/web/static/src/js/chrome/search_menus.js
+++ b/addons/web/static/src/js/chrome/search_menus.js
@@ -97,10 +97,15 @@ return Widget.extend({
}
var user_context = this.getSession().user_context;
var search = this.searchview.build_search_data();
- var view_context = this.action.env.context;
+ var controllerContext;
+ this.trigger_up('get_controller_context', {
+ callback: function (ctx) {
+ controllerContext = ctx;
+ },
+ });
var results = pyeval.eval_domains_and_contexts({
domains: search.domains,
- contexts: [user_context].concat(search.contexts.concat(view_context || [])),
+ contexts: [user_context].concat(search.contexts.concat(controllerContext || [])),
group_by_seq: search.groupbys || [],
});
if (!_.isEmpty(results.group_by)) {
@@ -123,7 +128,7 @@ return Widget.extend({
is_default: default_filter,
action_id: this.action_id,
};
- return data_manager.create_filter(filter).done(function (id) {
+ return this._createFilter(filter).then(function (id) {
filter.id = id;
self.toggle_save_menu(false);
self.$save_name.find('input').val('').prop('checked', false);
@@ -273,6 +278,26 @@ return Widget.extend({
}
});
},
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Creates a new search view filter.
+ *
+ * @private
+ * @param {Object} filter the filter description
+ * @returns {$.Deferred} resolved with the RPC's result when it succeeds
+ */
+ _createFilter: function (filter) {
+ var def = $.Deferred();
+ this.trigger_up('create_filter', {
+ filter: filter,
+ on_success: def.resolve.bind(def),
+ });
+ return def;
+ },
});
});