summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2016-09-30 17:23:30 +0200
committerChristophe Simonis <chs@odoo.com>2016-09-30 17:23:30 +0200
commitc8cc54559b75a621e4444ecdca6abd901b45e494 (patch)
tree92141325d4dbbf70bbfb8e0c040d4435c8d2378f /addons/web/static/src/js
parentb2804b1d2ae5fd7ec5c0eca79a8db77476badc84 (diff)
parent91a14488250bc2bb405cc6d300359aa272642484 (diff)
[MERGE] forward port branch 10.0 up to 91a1448
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/abstract_web_client.js16
-rw-r--r--addons/web/static/src/js/action_manager.js25
-rw-r--r--addons/web/static/src/js/framework/data_manager.js47
-rw-r--r--addons/web/static/src/js/framework/dialog.js2
-rw-r--r--addons/web/static/src/js/views/form_relational_widgets.js2
-rw-r--r--addons/web/static/src/js/widgets/debug_manager.js27
-rw-r--r--addons/web/static/src/js/widgets/systray_menu.js7
7 files changed, 98 insertions, 28 deletions
diff --git a/addons/web/static/src/js/abstract_web_client.js b/addons/web/static/src/js/abstract_web_client.js
index c3985f4cf5c..115a58a654f 100644
--- a/addons/web/static/src/js/abstract_web_client.js
+++ b/addons/web/static/src/js/abstract_web_client.js
@@ -30,6 +30,19 @@ var WebClient = Widget.extend({
toggle_fullscreen: function (event) {
this.toggle_fullscreen(event.data.fullscreen);
},
+ current_action_updated: function (e) {
+ this.current_action_updated(e.data.action);
+ },
+ perform_rpc: function(event) {
+ if (event.data.on_fail) {
+ event.data.on_fail();
+ }
+ },
+ perform_model_rpc: function(event) {
+ if (event.data.on_fail) {
+ event.data.on_fail();
+ }
+ },
},
init: function(parent) {
this.client_options = {};
@@ -220,6 +233,9 @@ var WebClient = Widget.extend({
this.connection_notification = false;
}
},
+ // Handler to be overwritten
+ current_action_updated: function () {
+ },
// --------------------------------------------------------------
// Scrolltop handling
// --------------------------------------------------------------
diff --git a/addons/web/static/src/js/action_manager.js b/addons/web/static/src/js/action_manager.js
index fe50fb65e90..b6a33e443d1 100644
--- a/addons/web/static/src/js/action_manager.js
+++ b/addons/web/static/src/js/action_manager.js
@@ -93,6 +93,12 @@ var Action = core.Class.extend({
get_fragment: function() {
return this.$fragment;
},
+ /**
+ * @return {string} the active view, i.e. empty for client actions
+ */
+ get_active_view: function() {
+ return '';
+ },
});
/**
* Specialization of Action for client actions that are Widgets
@@ -196,6 +202,12 @@ var ViewManagerAction = WidgetAction.extend({
get_nb_views: function() {
return this.widget.view_stack.length;
},
+ /**
+ * @return {string} the active view of the ViewManager
+ */
+ get_active_view: function() {
+ return this.widget.active_view.type;
+ }
});
var ActionManager = Widget.extend({
@@ -269,11 +281,15 @@ var ActionManager = Widget.extend({
var old_action_stack = this.action_stack;
var old_action = this.inner_action;
var old_widget = this.inner_widget;
+ var actions_to_destroy;
options = options || {};
- // Empty action_stack if requested
+ // Empty action_stack or replace last action if requested
if (options.clear_breadcrumbs) {
+ actions_to_destroy = this.action_stack;
this.action_stack = [];
+ } else if (options.replace_last_action && this.action_stack.length > 0) {
+ actions_to_destroy = [this.action_stack.pop()];
}
// Instantiate the new action
@@ -318,10 +334,11 @@ var ActionManager = Widget.extend({
in_DOM: self.is_in_DOM,
callbacks: [{widget: self.inner_widget}],
});
- if (options.clear_breadcrumbs) {
- self.clear_action_stack(old_action_stack);
+ if (actions_to_destroy) {
+ self.clear_action_stack(actions_to_destroy);
}
self.toggle_fullscreen();
+ self.trigger_up('current_action_updated', {action: new_action});
}).fail(function () {
// Destroy failed action and restore internal state
new_action.destroy();
@@ -404,6 +421,7 @@ var ActionManager = Widget.extend({
callbacks: [{widget: action.widget}],
});
}
+ self.trigger_up('current_action_updated', {action: action});
});
}).fail(function() {
return $.Deferred().reject();
@@ -561,6 +579,7 @@ var ActionManager = Widget.extend({
do_action: function(action, options) {
options = _.defaults(options || {}, {
clear_breadcrumbs: false,
+ replace_last_action: false,
on_reverse_breadcrumb: function() {},
hide_breadcrumb: false,
on_close: function() {},
diff --git a/addons/web/static/src/js/framework/data_manager.js b/addons/web/static/src/js/framework/data_manager.js
index 29d6d585f6a..55a4b4da15b 100644
--- a/addons/web/static/src/js/framework/data_manager.js
+++ b/addons/web/static/src/js/framework/data_manager.js
@@ -6,9 +6,19 @@ var Model = require('web.DataModel');
var session = require('web.session');
var utils = require('web.utils');
+function traverse(tree, f) {
+ if (f(tree)) {
+ _.each(tree.children, function(c) { traverse(c, f); });
+ }
+}
+
return core.Class.extend({
init: function () {
this.Filters = new Model('ir.filters');
+ this._init_cache();
+ },
+
+ _init_cache: function () {
this._cache = {
actions: {},
fields_views: {},
@@ -19,6 +29,14 @@ return core.Class.extend({
},
/**
+ * Invalidates the whole cache
+ * Suggestion: could be refined to invalidate some part of the cache
+ */
+ invalidate: function () {
+ this._init_cache();
+ },
+
+ /**
* Loads an action from its id or xmlid.
*
* @param {int|string} [action_id] the action id or xmlid
@@ -196,19 +214,46 @@ return core.Class.extend({
*/
_postprocess_fvg: function (fields_view) {
var self = this;
+
+ // Parse and process arch
var doc = $.parseXML(fields_view.arch).documentElement;
+ var fields = fields_view.fields;
fields_view.arch = utils.xml_to_json(doc, (doc.nodeName.toLowerCase() !== 'kanban'));
+ traverse(fields_view.arch, function(node) {
+ if (typeof node === 'string') {
+ return false;
+ }
+ if (node.tag === 'field') {
+ fields[node.attrs.name].__attrs = node.attrs;
+ if (fields[node.attrs.name].type === 'many2one') { // FIXME: this shouldn't be done here
+ if (node.attrs.widget === 'statusbar' || node.attrs.widget === 'radio') {
+ fields[node.attrs.name].__fetch_status = true;
+ } else if (node.attrs.widget === 'selection') {
+ fields[node.attrs.name].__fetch_selection = true;
+ }
+ }
+ if (node.attrs.widget === 'many2many_checkboxes') {
+ fields[node.attrs.name].__fetch_many2manys = true;
+ }
+ return false;
+ }
+ return node.tag !== 'arch';
+ });
+
+ // Special case for id's
if ('id' in fields_view.fields) {
- // Special case for id's
var id_field = fields_view.fields.id;
id_field.original_type = id_field.type;
id_field.type = 'id';
}
+
+ // Process inner views (one2manys)
_.each(fields_view.fields, function(field) {
_.each(field.views || {}, function(view) {
self._postprocess_fvg(view);
});
});
+
return fields_view;
},
diff --git a/addons/web/static/src/js/framework/dialog.js b/addons/web/static/src/js/framework/dialog.js
index d527dcf31d8..f23de4f426f 100644
--- a/addons/web/static/src/js/framework/dialog.js
+++ b/addons/web/static/src/js/framework/dialog.js
@@ -69,6 +69,7 @@ var Dialog = Widget.extend({
if(this.$content) {
this.setElement(this.$content);
}
+ this.$el.addClass('modal-body ' + this.dialogClass);
},
set_buttons: function(buttons) {
@@ -118,7 +119,6 @@ var Dialog = Widget.extend({
var self = this;
this.replace(this.$modal.find(".modal-body")).then(function() {
- self.$el.addClass('modal-body ' + self.dialogClass);
self.$modal.modal('show');
self._opened.resolve();
});
diff --git a/addons/web/static/src/js/views/form_relational_widgets.js b/addons/web/static/src/js/views/form_relational_widgets.js
index 4ce7ed6dbf3..dd4c4fb0fb6 100644
--- a/addons/web/static/src/js/views/form_relational_widgets.js
+++ b/addons/web/static/src/js/views/form_relational_widgets.js
@@ -955,7 +955,7 @@ var X2ManyListView = ListView.extend({
field.no_rerender = true;
current_values[field.name] = field.get('value');
});
- var cached_records = _.filter(this.dataset.cache, function(item){return !_.isEmpty(item.values);});
+ var cached_records = _.filter(this.dataset.cache, function(item){return !_.isEmpty(item.values) && !item.to_delete;});
var valid = _.every(cached_records, function(record){
_.each(fields, function(field){
var value = record.values[field.name];
diff --git a/addons/web/static/src/js/widgets/debug_manager.js b/addons/web/static/src/js/widgets/debug_manager.js
index f191eb739ea..f7ddd008e1d 100644
--- a/addons/web/static/src/js/widgets/debug_manager.js
+++ b/addons/web/static/src/js/widgets/debug_manager.js
@@ -48,7 +48,6 @@ var DebugManager = Widget.extend({
}
},
start: function () {
- core.bus.on('current_action_updated', this, this.update.bind(this, 'action'));
core.bus.on('rpc:result', this, function (req, resp) {
this._debug_events(resp.debug);
});
@@ -647,26 +646,12 @@ if (core.debug) {
SystrayMenu.Items.push(DebugManager);
WebClient.include({
- start: function() {
- var self = this;
- return this._super().then(function () {
- // Override push_action and select_action so that it triggers
- // an event each time a new action is pushed.
- // The DebugManager listens to this event to keep itself up-to-date
- var push_action = self.action_manager.push_action;
- self.action_manager.push_action = function(widget, descr) {
- return push_action.apply(self.action_manager, arguments).then(function () {
- core.bus.trigger('current_action_updated', descr, widget);
- });
- };
- var select_action = self.action_manager.select_action;
- self.action_manager.select_action = function() {
- return select_action.apply(self.action_manager, arguments).then(function () {
- var action = self.action_manager.get_inner_action();
- core.bus.trigger('current_action_updated', action.action_descr, action.widget);
- });
- };
- });
+ current_action_updated: function(action) {
+ this._super.apply(this, arguments);
+ var action_descr = action && action.action_descr;
+ var action_widget = action && action.widget;
+ var debug_manager = _.find(this.systray_menu.widgets, function(item) {return item instanceof DebugManager; });
+ debug_manager.update('action', action_descr, action_widget);
},
});
diff --git a/addons/web/static/src/js/widgets/systray_menu.js b/addons/web/static/src/js/widgets/systray_menu.js
index 131954de15f..0d0e18476b0 100644
--- a/addons/web/static/src/js/widgets/systray_menu.js
+++ b/addons/web/static/src/js/widgets/systray_menu.js
@@ -11,6 +11,7 @@ var SystrayMenu = Widget.extend({
init: function(parent) {
this._super(parent);
this.items = [];
+ this.widgets = [];
this.load = $.Deferred();
},
start: function() {
@@ -24,9 +25,13 @@ var SystrayMenu = Widget.extend({
},
load_items: function() {
var self = this;
+ SystrayMenu.Items = _.sortBy(SystrayMenu.Items, function (item) {
+ return !_.isUndefined(item.prototype.sequence) ? item.prototype.sequence : 50;
+ });
_.each(SystrayMenu.Items, function(widgetCls) {
var cur_systray_item = new widgetCls(self);
- self.items.push(cur_systray_item.appendTo(self.$el));
+ self.widgets.push(cur_systray_item);
+ self.items.push(cur_systray_item.prependTo(self.$el));
});
},
});