summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2015-02-12 18:03:27 +0100
committerAaron Bohy <aab@odoo.com>2015-03-20 16:18:35 +0100
commit7aa08364200936883b62a8389a5da714d0a40d6b (patch)
tree5c05fbb914d2dc531ed77ef1ea4700f11a406b84 /addons/web/static/src/js
parent151c90743efd374e72bf1b18f5ae0c392a3811ac (diff)
[IMP] Web: views.js, view_editor.js: DebugManager
Creation of a widget for the DebugManager and move it from the ControlPanel to the Systray. Refactoring of the widget to improve/facilitate the way of adding options in the DebugManager as the view_editor does. Add a do_action() function in the WebClient that forwards the action to the main ActionManager so that widget that are not in the scope of the ActionManager (e.g. Menu) can performed actions as well. Note: The DebugManager is currently in the Systray but it will finally be moved to a dedicated spot above the ControlPanel.
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/action_manager.js6
-rw-r--r--addons/web/static/src/js/control_panel.js178
-rw-r--r--addons/web/static/src/js/view_manager.js3
-rw-r--r--addons/web/static/src/js/web_client.js7
-rw-r--r--addons/web/static/src/js/widgets/debug_manager.js225
5 files changed, 244 insertions, 175 deletions
diff --git a/addons/web/static/src/js/action_manager.js b/addons/web/static/src/js/action_manager.js
index 8c560830493..5ae35308bfc 100644
--- a/addons/web/static/src/js/action_manager.js
+++ b/addons/web/static/src/js/action_manager.js
@@ -25,6 +25,8 @@ var State = core.Class.extend({
get_flags: function() { return this.flags; },
get_action: function() {},
get_active_view: function() {},
+ get_dataset: function() {},
+ get_searchview: function() {},
});
var WidgetState = State.extend({
@@ -47,6 +49,8 @@ var WidgetState = State.extend({
get_cp_content: function() { return this.cp_content; },
get_action: function() { return this.widget.action; },
get_active_view: function() { return this.widget.active_view; },
+ get_dataset: function() { return this.widget.dataset; },
+ get_searchview: function() { return this.widget.get_search_view(); },
destroy: function() {
if (this.cp_content && this.cp_content.searchview) {
this.cp_content.searchview.destroy();
@@ -557,7 +561,7 @@ var ActionManager = Widget.extend({
},
ir_actions_client: function (action, options) {
var self = this;
- var ClientWidget = core.action_registry.get_object(action.tag);
+ var ClientWidget = core.action_registry.get(action.tag);
if (!ClientWidget) {
return self.do_warn("Action Error", "Could not find client action '" + action.tag + "'.");
}
diff --git a/addons/web/static/src/js/control_panel.js b/addons/web/static/src/js/control_panel.js
index b71aefa60f1..d452c70120e 100644
--- a/addons/web/static/src/js/control_panel.js
+++ b/addons/web/static/src/js/control_panel.js
@@ -2,20 +2,14 @@ odoo.define('web.ControlPanel', function (require) {
"use strict";
var core = require('web.core');
-var Dialog = require('web.Dialog');
-var formats = require('web.formats');
-var framework = require('web.framework');
var SearchView = require('web.SearchView');
-var utils = require('web.utils');
var Widget = require('web.Widget');
var QWeb = core.qweb;
-var _t = core._t;
var ControlPanel = Widget.extend({
template: 'ControlPanel',
events: {
- "click .oe_debug_view": "on_debug_changed",
"click .oe-cp-switch-buttons button": "on_switch_buttons_click",
},
/**
@@ -38,8 +32,6 @@ var ControlPanel = Widget.extend({
this.searchview = null;
this.flags = null;
- this.dataset = null;
- this.active_view = null;
this.title = null; // Needed for Favorites of searchview
},
start: function() {
@@ -71,8 +63,10 @@ var ControlPanel = Widget.extend({
get_bus: function() {
return this.bus;
},
- // Sets the state of the controlpanel (in the case of a viewmanager, set_state must be
- // called before switch_mode for the controlpanel and the viewmanager to be synchronized)
+ /**
+ * Sets the state of the controlpanel (in the case of a viewmanager, set_state must be
+ * called before switch_mode for the controlpanel and the viewmanager to be synchronized)
+ */
set_state: function(state, old_state) {
// Detach control panel elements in which sub-elements are inserted by other widgets
var old_content = {
@@ -93,8 +87,6 @@ var ControlPanel = Widget.extend({
this.flags = state.get_flags();
this.flags = state.widget.flags;
- this.active_view = state.widget.active_view;
- this.dataset = state.widget.dataset;
this.title = state.widget.title; // needed for Favorites of searchview
// Hide the ControlPanel in headless mode
@@ -153,12 +145,9 @@ var ControlPanel = Widget.extend({
* @param {Array} [breadcrumbs] the breadcrumbs to display
*/
update: function(active_view, search_view_hidden, breadcrumbs) {
- this.active_view = active_view; // this.active_view only used for debug view
-
this.update_switch_buttons(active_view);
this.update_search_view(search_view_hidden);
this.update_breadcrumbs(breadcrumbs);
- this.render_debug_view();
},
/**
* Removes active class on all switch-buttons and adds it to the one of the active view
@@ -244,165 +233,6 @@ var ControlPanel = Widget.extend({
this.$search_col.toggle(!is_hidden);
}
},
- on_debug_changed: function (evt) {
- var self = this,
- params = $(evt.target).data(),
- val = params.action,
- current_view = this.active_view.controller;
- switch (val) {
- case 'fvg':
- var dialog = new Dialog(this, { title: _t("Fields View Get") }).open();
- $('<pre>').text(utils.json_node_to_xml(current_view.fields_view.arch, true)).appendTo(dialog.$el);
- break;
- case 'tests':
- this.do_action({
- name: _t("JS Tests"),
- target: 'new',
- type : 'ir.actions.act_url',
- url: '/web/tests?mod=*'
- });
- break;
- case 'get_metadata':
- var ids = current_view.get_selected_ids();
- if (ids.length === 1) {
- this.dataset.call('get_metadata', [ids]).done(function(result) {
- new Dialog(this, {
- title: _.str.sprintf(_t("Metadata (%s)"), self.dataset.model),
- size: 'medium',
- buttons: {
- Ok: function() { this.parents('.modal').modal('hide');}
- },
- }, QWeb.render('ViewManagerDebugViewLog', {
- perm : result[0],
- format : formats.format_value
- })).open();
- });
- }
- break;
- case 'toggle_layout_outline':
- current_view.rendering_engine.toggle_layout_debugging();
- break;
- case 'set_defaults':
- current_view.open_defaults_dialog();
- break;
- case 'translate':
- this.do_action({
- name: _t("Technical Translation"),
- res_model : 'ir.translation',
- domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']],
- views: [[false, 'list'], [false, 'form']],
- type : 'ir.actions.act_window',
- view_type : "list",
- view_mode : "list"
- });
- break;
- case 'fields':
- this.dataset.call('fields_get', [false, {}]).done(function (fields) {
- var $root = $('<dl>');
- _(fields).each(function (attributes, name) {
- $root.append($('<dt>').append($('<h4>').text(name)));
- var $attrs = $('<dl>').appendTo($('<dd>').appendTo($root));
- _(attributes).each(function (def, name) {
- if (def instanceof Object) {
- def = JSON.stringify(def);
- }
- $attrs
- .append($('<dt>').text(name))
- .append($('<dd style="white-space: pre-wrap;">').text(def));
- });
- });
- new Dialog(self, {
- title: _.str.sprintf(_t("Model %s fields"),
- self.dataset.model),
- buttons: {
- Ok: function() { this.parents('.modal').modal('hide');}
- },
- }, $root).open();
- });
- break;
- case 'edit_workflow':
- return this.do_action({
- res_model : 'workflow',
- name: _t('Edit Workflow'),
- domain : [['osv', '=', this.dataset.model]],
- views: [[false, 'list'], [false, 'form'], [false, 'diagram']],
- type : 'ir.actions.act_window',
- view_type : 'list',
- view_mode : 'list'
- });
- case 'edit':
- this.do_edit_resource(params.model, params.id, evt.target.text);
- break;
- case 'manage_filters':
- this.do_action({
- res_model: 'ir.filters',
- name: _t('Manage Filters'),
- views: [[false, 'list'], [false, 'form']],
- type: 'ir.actions.act_window',
- context: {
- search_default_my_filters: true,
- search_default_model_id: this.dataset.model
- }
- });
- break;
- case 'print_workflow':
- if (current_view.get_selected_ids && current_view.get_selected_ids().length == 1) {
- framework.blockUI();
- var action = {
- context: { active_ids: current_view.get_selected_ids() },
- report_name: "workflow.instance.graph",
- datas: {
- model: this.dataset.model,
- id: current_view.get_selected_ids()[0],
- nested: true,
- }
- };
- this.session.get_file({
- url: '/web/report',
- data: {action: JSON.stringify(action)},
- complete: framework.unblockUI
- });
- } else {
- self.do_warn("Warning", "No record selected.");
- }
- break;
- case 'leave_debug':
- window.location.search="?";
- break;
- default:
- if (val) {
- console.warn("No debug handler for ", val);
- }
- }
- },
- do_edit_resource: function(model, id, name) {
- this.do_action({
- res_model : model,
- res_id : id,
- name: name,
- type : 'ir.actions.act_window',
- view_type : 'form',
- view_mode : 'form',
- views : [[false, 'form']],
- target : 'new',
- flags : {
- action_buttons : true,
- headless: true,
- }
- });
- },
- /**
- * Renders the debug dropdown according to the active_view
- */
- render_debug_view: function() {
- var self = this;
- if (self.session.debug) {
- self.$('.oe_debug_view').html(QWeb.render('ViewManagerDebug', {
- view: self.active_view.controller,
- widget: self,
- }));
- }
- },
});
return ControlPanel;
diff --git a/addons/web/static/src/js/view_manager.js b/addons/web/static/src/js/view_manager.js
index 94af0912907..2438555e7a8 100644
--- a/addons/web/static/src/js/view_manager.js
+++ b/addons/web/static/src/js/view_manager.js
@@ -139,6 +139,9 @@ var ViewManager = Widget.extend({
this.searchview = searchview;
this.search_view_loaded = search_view_loaded_def;
},
+ get_search_view: function() {
+ return this.searchview;
+ },
/**
* Executed on event "search_data" thrown by the SearchView
*/
diff --git a/addons/web/static/src/js/web_client.js b/addons/web/static/src/js/web_client.js
index 4242559b1fb..1b99fddaef2 100644
--- a/addons/web/static/src/js/web_client.js
+++ b/addons/web/static/src/js/web_client.js
@@ -255,6 +255,13 @@ var WebClient = Widget.extend({
}
});
},
+ /**
+ * When do_action is performed on the WebClient, forward it to the main ActionManager
+ * This allows to widgets that are not inside the ActionManager to perform do_action
+ */
+ do_action: function() {
+ this.action_manager.do_action.apply(this, arguments);
+ },
destroy_content: function() {
_.each(_.clone(this.getChildren()), function(el) {
el.destroy();
diff --git a/addons/web/static/src/js/widgets/debug_manager.js b/addons/web/static/src/js/widgets/debug_manager.js
new file mode 100644
index 00000000000..4fffdab9294
--- /dev/null
+++ b/addons/web/static/src/js/widgets/debug_manager.js
@@ -0,0 +1,225 @@
+odoo.define('web.DebugManager', function (require) {
+"use strict";
+
+var core = require('web.core');
+var Dialog = require('web.Dialog');
+var formats = require('web.formats');
+var framework = require('web.framework');
+var session = require('web.session');
+var SystrayMenu = require('web.SystrayMenu');
+var utils = require('web.utils');
+var ViewManager = require('web.ViewManager');
+var Widget = require('web.Widget');
+
+var QWeb = core.qweb;
+var _t = core._t;
+
+if (core.debug) {
+ var DebugManager = Widget.extend({
+ template: "WebClient.DebugManager",
+ events: {
+ "click .oe_debug_button": "render_dropdown",
+ "click .js_debug_dropdown li": "on_debug_click",
+ },
+ start: function() {
+ this._super();
+ this.$dropdown = this.$(".js_debug_dropdown");
+ },
+ /**
+ * Updates its attributes according to the current state of the ActionManager
+ */
+ _update_state: function() {
+ this.view_manager = odoo.__DEBUG__.services['web.web_client'].action_manager.get_inner_widget();
+ if (!this.view_manager instanceof ViewManager) { return; }
+ this.dataset = this.view_manager.dataset;
+ this.active_view = this.view_manager.active_view;
+ if (!this.active_view) { return; }
+ this.view = this.active_view.controller;
+ return true;
+ },
+ /**
+ * Renders dropdown according to the current state
+ */
+ render_dropdown: function() {
+ var self = this;
+
+ // Empty the previously rendered dropdown
+ this.$dropdown.empty();
+
+ // Attempt to retrieve the current state of the ActionManager
+ if (!this._update_state()) {
+ // Disable the button when not available
+ console.warn("DebugManager is not available");
+ return;
+ }
+
+ // Render the dropdown and append it
+ var dropdown_content = QWeb.render('WebClient.DebugDropdown', {
+ widget: self,
+ active_view: self.active_view,
+ view: self.view,
+ action: self.view_manager.action,
+ searchview: self.view_manager.searchview,
+ uid: session.uid,
+ });
+ $(dropdown_content).appendTo(self.$dropdown);
+ },
+ /**
+ * Calls the appropriate callback when clicking on a Debug option
+ */
+ on_debug_click: function (evt) {
+ evt.preventDefault();
+
+ var params = $(evt.target).data();
+ var callback = params.action;
+
+ if (callback && this[callback]) {
+ // Perform the callback corresponding to the option
+ this[callback](params, evt);
+ } else {
+ console.warn("No debug handler for ", callback);
+ }
+ },
+ get_metadata: function() {
+ var self = this;
+ var ids = this.view.get_selected_ids();
+ if (ids.length === 1) {
+ self.dataset.call('get_metadata', [ids]).done(function(result) {
+ new Dialog(this, {
+ title: _.str.sprintf(_t("Metadata (%s)"), self.dataset.model),
+ size: 'medium',
+ buttons: {
+ Ok: function() { this.parents('.modal').modal('hide');}
+ },
+ }, QWeb.render('WebClient.DebugViewLog', {
+ perm : result[0],
+ format : formats.format_value
+ })).open();
+ });
+ }
+ },
+ toggle_layout_outline: function() {
+ this.view.rendering_engine.toggle_layout_debugging();
+ },
+ set_defaults: function() {
+ this.view.open_defaults_dialog();
+ },
+ perform_js_tests: function() {
+ this.do_action({
+ name: _t("JS Tests"),
+ target: 'new',
+ type : 'ir.actions.act_url',
+ url: '/web/tests?mod=*'
+ });
+ },
+ get_view_fields: function() {
+ var self = this;
+ self.dataset.call('fields_get', [false, {}]).done(function (fields) {
+ var $root = $('<dl>');
+ _(fields).each(function (attributes, name) {
+ $root.append($('<dt>').append($('<h4>').text(name)));
+ var $attrs = $('<dl>').appendTo($('<dd>').appendTo($root));
+ _(attributes).each(function (def, name) {
+ if (def instanceof Object) {
+ def = JSON.stringify(def);
+ }
+ $attrs
+ .append($('<dt>').text(name))
+ .append($('<dd style="white-space: pre-wrap;">').text(def));
+ });
+ });
+ new Dialog(self, {
+ title: _.str.sprintf(_t("Model %s fields"),
+ self.dataset.model),
+ buttons: {
+ Ok: function() { this.parents('.modal').modal('hide');}
+ },
+ }, $root).open();
+ });
+ },
+ fvg: function() {
+ var dialog = new Dialog(this, { title: _t("Fields View Get") }).open();
+ $('<pre>').text(utils.json_node_to_xml(this.view.fields_view.arch, true)).appendTo(dialog.$el);
+ },
+ manage_filters: function() {
+ this.do_action({
+ res_model: 'ir.filters',
+ name: _t('Manage Filters'),
+ views: [[false, 'list'], [false, 'form']],
+ type: 'ir.actions.act_window',
+ context: {
+ search_default_my_filters: true,
+ search_default_model_id: this.dataset.model
+ }
+ });
+ },
+ translate: function() {
+ this.do_action({
+ name: _t("Technical Translation"),
+ res_model : 'ir.translation',
+ domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']],
+ views: [[false, 'list'], [false, 'form']],
+ type : 'ir.actions.act_window',
+ view_type : "list",
+ view_mode : "list"
+ });
+ },
+ edit: function(params, evt) {
+ this.do_action({
+ res_model : params.model,
+ res_id : params.id,
+ name: evt.target.text,
+ type : 'ir.actions.act_window',
+ view_type : 'form',
+ view_mode : 'form',
+ views : [[false, 'form']],
+ target : 'new',
+ flags : {
+ action_buttons : true,
+ headless: true,
+ }
+ });
+ },
+ edit_workflow: function() {
+ return this.do_action({
+ res_model : 'workflow',
+ name: _t('Edit Workflow'),
+ domain : [['osv', '=', this.dataset.model]],
+ views: [[false, 'list'], [false, 'form'], [false, 'diagram']],
+ type : 'ir.actions.act_window',
+ view_type : 'list',
+ view_mode : 'list'
+ });
+ },
+ print_workflow: function() {
+ if (this.view.get_selected_ids && this.view.get_selected_ids().length == 1) {
+ framework.blockUI();
+ var action = {
+ context: { active_ids: this.view.get_selected_ids() },
+ report_name: "workflow.instance.graph",
+ datas: {
+ model: this.dataset.model,
+ id: this.view.get_selected_ids()[0],
+ nested: true,
+ }
+ };
+ this.session.get_file({
+ url: '/web/report',
+ data: {action: JSON.stringify(action)},
+ complete: framework.unblockUI
+ });
+ } else {
+ this.do_warn("Warning", "No record selected.");
+ }
+ },
+ leave_debug: function() {
+ window.location.search="?";
+ },
+ });
+
+ SystrayMenu.Items.push(DebugManager);
+
+ return DebugManager;
+}
+
+});