summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/core
diff options
context:
space:
mode:
authorGéry Debongnie <ged@odoo.com>2018-12-06 12:39:06 +0000
committerGéry Debongnie <ged@odoo.com>2018-12-07 13:16:06 +0000
commit40dd121938552d3f88289d2e5fcd1d57a0dd01bb (patch)
tree4830c8ffdea1e10d35c7ddf096f536bd8999240f /addons/web/static/src/js/core
parent48a50b4bc011fc6dfc82a673f921fad941dc79cf (diff)
[REF] web: move ControlPanel inside controllers/actions
This branch introduces a large-scale reorganization of the component tree generated by the web client. The short version is that now, the control panel is a child of the view controller and no longer a sibling. Graphically (and simplified), we go from this: webClient / | \ ... ... actionManager / \ controlPanel viewController / \ to this: webClient / | \ ... ... actionManager | viewController / | \ ControlPanelController / \ CPRenderer CPModel The motivation is that this work moves the code where it should be. Before this commit, it was kind of weird to have code in the controllers to render buttons outside of their root node (in renderButtons). Also, the action manager had to take care of coordinating search view states between view transitions. So, this work simplifies the code. It also makes it easier to extend. We see day after day that Odoo needs to take care of more complex UI needs, and in many cases, these needs were quite difficult to implement (we prefer spaghettis in our plates, not in our code). The changes in this branch should open the way to implement these features. For example, - it will now be easy to add the possibility of views (for example, the search view or a new ControlPanel view) to add custom buttons (of type action or object) in the control panel. - Another need will be to serialize/ restore the state of the search view across action boundaries (needed by the dashboard). - Another example is the possibility for views to customize easily the presence/absence of sub menus (filters/groupbys/favorites/ time range/...) - Another need is an easier way for views/client action to customize their control panel. This commit also contains a large rewrite of the search view (so it is more inline with our architecture and easier to maintain). Part of task 1893568 Co-authored-by: Aaron Bohy <aab@odoo.com> Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com> Co-authored-by: Martin Geubelle <mge@odoo.com>
Diffstat (limited to 'addons/web/static/src/js/core')
-rw-r--r--addons/web/static/src/js/core/registry.js51
-rw-r--r--addons/web/static/src/js/core/service_mixins.js27
2 files changed, 61 insertions, 17 deletions
diff --git a/addons/web/static/src/js/core/registry.js b/addons/web/static/src/js/core/registry.js
index f925b0ea30a..c6d35229639 100644
--- a/addons/web/static/src/js/core/registry.js
+++ b/addons/web/static/src/js/core/registry.js
@@ -25,6 +25,8 @@ var Registry = Class.extend({
*/
init: function (mapping) {
this.map = Object.create(mapping || null);
+ this._scoreMapping = Object.create(null);
+ this._sortedKeys = null;
this.listeners = []; // listening callbacks on newly added items.
},
@@ -39,9 +41,12 @@ var Registry = Class.extend({
*
* @param {string} key
* @param {any} value
+ * @param {[number]} score if given, this value will be used to order keys
* @returns {Registry} can be used to chain add calls.
*/
- add: function (key, value) {
+ add: function (key, value, score) {
+ this._scoreMapping[key] = score === undefined ? key : score;
+ this._sortedKeys = null;
this.map[key] = value;
_.each(this.listeners, function (callback) {
callback(key, value);
@@ -49,7 +54,7 @@ var Registry = Class.extend({
return this;
},
/**
- * Check if the registry contains the value
+ * Check if the registry contains the key
*
* @param {string} key
* @returns {boolean}
@@ -58,18 +63,12 @@ var Registry = Class.extend({
return (key in this.map);
},
/**
- * Creates and returns a copy of the current mapping, with the provided
- * mapping argument added in (replacing existing keys if needed)
+ * Returns the content of the registry (an object mapping keys to values)
*
- * Parent and child remain linked, a new key in the parent (which is not
- * overwritten by the child) will appear in the child.
- *
- * @param {Object} [mapping={}] a mapping of keys to object-paths
+ * @returns {Object}
*/
- extend: function (mapping) {
- var child = new Registry(this.map);
- _.extend(child.map, mapping);
- return child;
+ entries: function () {
+ return Object.create(this.map);
},
/**
* Returns the value associated to the given key.
@@ -96,6 +95,23 @@ var Registry = Class.extend({
return null;
},
/**
+ * Return the list of keys in map object.
+ *
+ * The registry guarantees that the keys have a consistent order, defined by
+ * the 'score' value when the item has been added.
+ *
+ * @returns {string[]}
+ */
+ keys: function () {
+ var self = this;
+ if (!this._sortedKeys) {
+ this._sortedKeys = _.sortBy(Object.keys(this.map), function (key) {
+ return self._scoreMapping[key] || 0;
+ });
+ }
+ return this._sortedKeys;
+ },
+ /**
* Register a callback to execute when items are added to the registry.
*
* @param {function} callback function with parameters (key, value).
@@ -103,6 +119,17 @@ var Registry = Class.extend({
onAdd: function (callback) {
this.listeners.push(callback);
},
+ /**
+ * Return the list of values in map object
+ *
+ * @returns {string[]}
+ */
+ values: function () {
+ var self = this;
+ return this.keys().map(function (key) {
+ return self.map[key];
+ });
+ },
});
return Registry;
diff --git a/addons/web/static/src/js/core/service_mixins.js b/addons/web/static/src/js/core/service_mixins.js
index 9c127a1bc8c..e8088d45cb5 100644
--- a/addons/web/static/src/js/core/service_mixins.js
+++ b/addons/web/static/src/js/core/service_mixins.js
@@ -139,8 +139,8 @@ var ServicesMixin = {
promise.abort = abort.bind(def);
return promise;
},
- loadFieldView: function (dataset, view_id, view_type, options) {
- return this.loadViews(dataset.model, dataset.get_context().eval(), [[view_id, view_type]], options).then(function (result) {
+ loadFieldView: function (modelName, context, view_id, view_type, options) {
+ return this.loadViews(modelName, context, [[view_id, view_type]], options).then(function (result) {
return result[view_type];
});
},
@@ -155,11 +155,28 @@ var ServicesMixin = {
});
return def;
},
- loadFilters: function (dataset, action_id) {
+ loadFilters: function (modelName, actionId, context) {
var def = $.Deferred();
this.trigger_up('load_filters', {
- dataset: dataset,
- action_id: action_id,
+ modelName: modelName,
+ actionId: actionId,
+ context: context,
+ on_success: def.resolve.bind(def),
+ });
+ return def;
+ },
+ createFilter: function (filter) {
+ var def = $.Deferred();
+ this.trigger_up('create_filter', {
+ filter: filter,
+ on_success: def.resolve.bind(def),
+ });
+ return def;
+ },
+ deleteFilter: function (filterId) {
+ var def = $.Deferred();
+ this.trigger_up('delete_filter', {
+ filterId: filterId,
on_success: def.resolve.bind(def),
});
return def;