1 openerp.web_dashboard = function(openerp) {
2 var QWeb = openerp.web.qweb;
4 if (!openerp.web_dashboard) {
6 openerp.web_dashboard = {};
9 openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
10 init: function(view, node) {
11 this._super(view, node);
12 this.template = 'DashBoard';
13 this.actions_attrs = {};
14 this.action_managers = [];
18 this._super.apply(this, arguments);
20 this.$element.find('.oe-dashboard-column').sortable({
21 connectWith: '.oe-dashboard-column',
22 handle: '.oe-dashboard-action-header',
24 }).disableSelection().bind('sortstop', self.do_save_dashboard);
27 this.$element.find('.oe-dashboard-link-reset').click(this.on_reset);
28 this.$element.find('.oe-dashboard-link-change_layout').click(this.on_change_layout);
30 this.$element.delegate('.oe-dashboard-column .oe-dashboard-fold', 'click', this.on_fold_action);
31 this.$element.delegate('.oe-dashboard-column .ui-icon-closethick', 'click', this.on_close_action);
33 this.actions_attrs = {};
35 _.each(this.node.children, function(column, column_index) {
36 _.each(column.children, function(action, action_index) {
37 delete(action.attrs.width);
38 delete(action.attrs.height);
39 delete(action.attrs.colspan);
40 self.actions_attrs[action.attrs.name] = action.attrs;
41 self.rpc('/web/action/load', {
42 action_id: parseInt(action.attrs.name, 10)
44 self.on_load_action(result, column_index + '_' + action_index);
49 on_reset: function() {
50 this.rpc('/web/view/undo_custom', {
51 view_id: this.view.fields_view.view_id,
55 on_change_layout: function() {
58 current_layout : this.$element.find('.oe-dashboard').attr('data-layout')
60 var $dialog = $('<div>').dialog({
65 }).html(QWeb.render('DashBoard.layouts', qdict));
66 $dialog.find('li').click(function() {
67 var layout = $(this).attr('data-layout');
68 $dialog.dialog('destroy');
69 self.do_change_layout(layout);
72 do_change_layout: function(new_layout) {
73 var $dashboard = this.$element.find('.oe-dashboard');
74 var current_layout = $dashboard.attr('data-layout');
75 if (current_layout != new_layout) {
76 var clayout = current_layout.split('-').length,
77 nlayout = new_layout.split('-').length,
78 column_diff = clayout - nlayout;
79 if (column_diff > 0) {
80 var $last_column = $();
81 $dashboard.find('.oe-dashboard-column').each(function(k, v) {
83 $(v).find('.oe-dashboard-action').appendTo($last_column);
89 $dashboard.toggleClass('oe-dashboard-layout_' + current_layout + ' oe-dashboard-layout_' + new_layout);
90 $dashboard.attr('data-layout', new_layout);
91 this.do_save_dashboard();
94 on_fold_action: function(e) {
95 var $e = $(e.currentTarget),
96 $action = $e.parents('.oe-dashboard-action:first'),
97 id = parseInt($action.attr('data-id'), 10);
98 if ($e.is('.ui-icon-minusthick')) {
99 this.actions_attrs[id].fold = '1';
101 delete(this.actions_attrs[id].fold);
103 $e.toggleClass('ui-icon-minusthick ui-icon-plusthick');
104 $action.find('.oe-dashboard-action-content').toggle();
105 this.do_save_dashboard();
107 on_close_action: function(e) {
108 if (confirm("Are you sure you want to remove this item ?")) {
109 $(e.currentTarget).parents('.oe-dashboard-action:first').remove();
110 this.do_save_dashboard();
113 do_save_dashboard: function() {
116 form_title : this.view.fields_view.arch.attrs.string,
117 style : this.$element.find('.oe-dashboard').attr('data-layout'),
120 this.$element.find('.oe-dashboard-column').each(function() {
122 $(this).find('.oe-dashboard-action').each(function() {
123 var action_id = $(this).attr('data-id'),
124 new_attrs = _.clone(self.actions_attrs[action_id]);
125 if (new_attrs.domain) {
126 new_attrs.domain = new_attrs.domain_string;
127 delete(new_attrs.domain_string);
129 if (new_attrs.context) {
130 new_attrs.context = new_attrs.context_string;
131 delete(new_attrs.context_string);
133 actions.push(new_attrs);
135 board.columns.push(actions);
137 var arch = QWeb.render('DashBoard.xml', board);
138 this.rpc('/web/view/add_custom', {
139 view_id: this.view.fields_view.view_id,
142 self.$element.find('.oe-dashboard-link-reset').show();
145 on_load_action: function(result, index) {
147 action = result.result,
148 action_attrs = this.actions_attrs[action.id],
149 view_mode = action_attrs.view_mode;
151 if (action_attrs.context) {
152 action.context = action_attrs.context;
154 if (action_attrs.domain) {
155 action.domain = action_attrs.domain;
157 var action_orig = _.extend({}, action);
159 if (view_mode && view_mode != action.view_mode) {
160 var action_view_mode = action.view_mode.split(',');
161 action.views = _.map(view_mode.split(','), function(mode) {
162 if (_.indexOf(action_view_mode, mode) < 0) {
163 return [false, mode == 'tree' ? 'list': mode];
165 mode = mode === 'tree' ? 'list' : mode;
166 return _.find(action.views, function(view) {
167 return view[1] == mode;
176 views_switcher : false,
177 action_buttons : false,
180 display_title: false,
185 var am = new openerp.web.ActionManager(this);
186 this.action_managers.push(am);
187 am.appendTo($('#' + this.view.element_id + '_action_' + index));
188 am.do_action(action);
189 am.do_action = function(action) {
190 self.do_action(action);
192 if (am.inner_viewmanager) {
193 am.inner_viewmanager.on_mode_switch.add(function(mode) {
195 _.each(action_orig.views, function(view) {
196 new_views[view[1] === mode ? 'unshift' : 'push'](view);
198 if (!new_views.length || new_views[0][1] !== mode) {
199 new_views.unshift([false, mode]);
201 action_orig.views = new_views;
202 action_orig.res_id = am.inner_viewmanager.dataset.ids[am.inner_viewmanager.dataset.index];
203 self.do_action(action_orig);
208 // We should start with three columns available
209 for (var i = this.node.children.length; i < 3; i++) {
210 this.node.children.push({
216 return QWeb.render(this.template, this);
218 do_reload: function() {
219 var view_manager = this.view.widget_parent,
220 action_manager = view_manager.widget_parent;
222 action_manager.do_action(view_manager.action);
225 openerp.web.form.DashBoardLegacy = openerp.web.form.DashBoard.extend({
227 if (this.node.tag == 'hpaned') {
228 this.node.attrs.style = '2-1';
229 } else if (this.node.tag == 'vpaned') {
230 this.node.attrs.style = '1';
232 this.node.tag = 'board';
233 _.each(this.node.children, function(child) {
234 if (child.tag.indexOf('child') == 0) {
235 child.tag = 'column';
236 var actions = [], first_child = child.children[0];
237 if (first_child && first_child.tag == 'vpaned') {
238 _.each(first_child.children, function(subchild) {
239 actions.push.apply(actions, subchild.children);
241 child.children = actions;
245 return this._super(this, arguments);
249 openerp.web.form.widgets.add('hpaned', 'openerp.web.form.DashBoardLegacy');
250 openerp.web.form.widgets.add('vpaned', 'openerp.web.form.DashBoardLegacy');
251 openerp.web.form.widgets.add('board', 'openerp.web.form.DashBoard');
255 * This client action designed to be used as a dashboard widget display
256 * ir.actions.todo in a fancy way
258 openerp.web.client_actions.add( 'board.config.overview', 'openerp.web_dashboard.ConfigOverview');
259 openerp.web_dashboard.ConfigOverview = openerp.web.View.extend({
260 template: 'ConfigOverview',
261 init: function (parent) {
263 this.dataset = new openerp.web.DataSetSearch(
264 this, 'ir.actions.todo');
265 this.dataset.domain = [['type', '!=', 'automatic']];
269 $.when(this.dataset.read_slice(['state', 'action_id', 'category_id']),
270 this.dataset.call('progress'))
271 .then(this.on_records_loaded);
273 on_records_loaded: function (read_response, progress_response) {
274 var records = read_response,
275 progress = progress_response[0];
277 var grouped_todos = _(records).chain()
278 .map(function (record) {
281 name: record.action_id[1],
282 done: record.state !== 'open',
283 to_do: record.state === 'open',
284 category: record['category_id'][1] || "Uncategorized"
287 .groupBy(function (record) {return record.category})
289 this.$element.html(QWeb.render('ConfigOverview.content', {
290 completion: 100 * progress.done / progress.total,
291 groups: grouped_todos
293 var $progress = this.$element.find('div.oe-config-progress-bar');
294 $progress.progressbar({value: $progress.data('completion')});
297 this.$element.find('dl')
298 .delegate('input', 'click', function (e) {
299 // switch todo status
300 e.stopImmediatePropagation();
301 var new_state = this.checked ? 'done' : 'open',
302 todo_id = parseInt($(this).val(), 10);
303 self.dataset.write(todo_id, {state: new_state}, {}, function () {
307 .delegate('li:not(.oe-done)', 'click', function () {
308 self.widget_parent.widget_parent.widget_parent.do_execute_action({
310 name: 'action_launch'
312 $(this).data('id'), function () {
313 // after action popup closed, refresh configuration
323 * This client action designed to be used as a dashboard widget display
324 * the html content of a res_widget given as argument
326 openerp.web.client_actions.add( 'board.home.widgets', 'openerp.web_dashboard.Widget');
327 openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_dashboard.Widgets# */{
328 template: 'HomeWidget',
330 * Initializes a "HomeWidget" client widget: handles the display of a given
331 * res.widget objects in an OpenERP view (mainly a dashboard).
333 * @constructs openerp.web_dashboard.Widget
334 * @extends openerp.web.View
336 * @param {Object} parent
337 * @param {Object} options
338 * @param {Number} options.widget_id
340 init: function (parent, options) {
342 this.widget_id = options.widget_id;
346 return new openerp.web.DataSet(this, 'res.widget').read_ids(
347 [this.widget_id], ['title'], this.on_widget_loaded);
349 on_widget_loaded: function (widgets) {
350 var widget = widgets[0];
351 var url = _.str.sprintf(
352 '/web_dashboard/widgets/content?session_id=%s&widget_id=%d',
353 this.session.session_id, widget.id);
354 this.$element.html(QWeb.render('HomeWidget.content', {
362 * HomeTiles this client action display either the list of application to
363 * install (if none is installed yet) or a list of root menu items
365 openerp.web.client_actions.add('default_home', 'session.web_dashboard.ApplicationTiles');
366 openerp.web_dashboard.ApplicationTiles = openerp.web.Widget.extend({
367 template: 'web_dashboard.ApplicationTiles',
368 init: function(parent) {
374 {module: 'crm', name: 'CRM', menu: 'Sales', help: "Acquire leads, follow opportunities, manage prospects and phone calls, \u2026"},
376 var domain = [['core','=',true],['state','=','installed']];
377 var ds = new openerp.web.DataSetSearch(this, 'ir.module.module',{},domain);
378 ds.read_slice(['id'], {}, function(result) {
380 self.on_installed_database();
382 self.on_uninstalled_database();
386 on_uninstalled_database: function() {
387 console.log("UNINSTALLED");
388 this.$element.html("ApplicationInstaller");
389 installer = new openerp.web_dashboard.ApplicationInstaller(this);
390 installer.appendTo(this.$element);
392 on_installed_database: function() {
393 console.log("INSTALLED");
394 this.$element.html("ApplicationTiles");
396 var ds = new openerp.web.DataSetSearch( this, 'ir.ui.menu', null, [['parent_id', '=', false]]);
397 var r = ds.read_slice( ['name', 'web_icon_data', 'web_icon_hover_data'], {}, function (applications) {
398 // Create a matrix of 3*x applications
400 while (applications.length) {
401 rows.push(applications.splice(0, 3));
403 var tiles = QWeb.render( 'ApplicationTiles.content', {rows: rows});
404 self.$element.append(tiles).find('.oe-dashboard-home-tile').click(function () {
405 openerp.webclient.menu.on_menu_click(null, $(this).data('menuid'))
412 * ApplicationInstaller
413 * This client action display a list of applications to install.
415 openerp.web.client_actions.add( 'board.application.installer', 'openerp.web_dashboard.ApplicationInstaller');
416 openerp.web_dashboard.ApplicationInstaller = openerp.web.View.extend({
417 template: 'web_dashboard.ApplicationInstaller',
420 $('.secondary_menu', this.$element.closest('.openerp')).hide();
421 this.$element.append("Display ir module module kanban view");
423 /* currenlt unused */
424 on_install_clicked: function() {
425 var Installer = new openerp.web.DataSet(this, 'base.setup.installer');
426 Installer.call('default_get', [], function (installed_modules) {
427 console.log(installed_modules);
428 self.$element.html(QWeb.render('Welcome-Page', {'applications': applications}));
429 self.$element.find('.install-module-link').click(function () {
430 self.install_module($(this).data('module'), $(this).data('menu'));
435 install_module: function (module_name, menu_name) {
437 var Modules = new openerp.web.DataSetSearch(
438 this, 'ir.module.module', null,
439 [['name', '=', module_name], ['state', '=', 'uninstalled']]);
440 var Upgrade = new openerp.web.DataSet(this, 'base.module.upgrade');
443 Modules.read_slice(['id'], {}, function (records) {
444 if (!(records.length === 1)) { $.unblockUI(); return; }
445 Modules.call('state_update',
446 [_.pluck(records, 'id'), 'to install', ['uninstalled']],
448 Upgrade.call('upgrade_module', [[]], function () {
449 self.run_configuration_wizards(menu_name);
455 run_configuration_wizards: function (menu_name) {
457 new openerp.web.DataSet(this, 'res.config').call('start', [[]], function (action) {
458 self.widget_parent.widget_parent.do_action(action, function () {
459 openerp.webclient.do_reload();
461 self.$element.empty();
462 var dss = new openerp.web.DataSetSearch(this, 'ir.ui.menu', null, [['parent_id', '=', false], ['name', '=', menu_name]]);
463 dss.read_slice(['id'], {}, function(menus) {
464 if(!(menus.length === 1)) { $.unblockUI(); return; }
465 $.when(openerp.webclient.menu.on_menu_click(null, menus[0].id)).then($.unblockUI);