1 openerp.web_dashboard = function(openerp) {
2 var QWeb = openerp.web.qweb;
3 QWeb.add_template('/web_dashboard/static/src/xml/web_dashboard.xml');
5 openerp.web.form.DashBoard = openerp.web.form.Widget.extend({
6 init: function(view, node) {
7 this._super(view, node);
8 this.template = 'DashBoard';
9 this.actions_attrs = {};
10 this.action_managers = [];
14 this._super.apply(this, arguments);
16 this.$element.find('.oe-dashboard-column').sortable({
17 connectWith: '.oe-dashboard-column',
18 handle: '.oe-dashboard-action-header',
20 }).disableSelection().bind('sortstop', self.do_save_dashboard);
23 this.$element.find('.oe-dashboard-link-undo').click(this.on_undo);
24 this.$element.find('.oe-dashboard-link-reset').click(this.on_reset);
25 this.$element.find('.oe-dashboard-link-add_widget').click(this.on_add_widget);
26 this.$element.find('.oe-dashboard-link-change_layout').click(this.on_change_layout);
28 this.$element.delegate('.oe-dashboard-column .oe-dashboard-fold', 'click', this.on_fold_action);
29 this.$element.delegate('.oe-dashboard-column .ui-icon-closethick', 'click', this.on_close_action);
31 this.actions_attrs = {};
33 _.each(this.node.children, function(column) {
34 _.each(column.children, function(action) {
35 delete(action.attrs.width);
36 delete(action.attrs.height);
37 delete(action.attrs.colspan);
38 self.actions_attrs[action.attrs.name] = action.attrs;
39 self.rpc('/web/action/load', {
40 action_id: parseInt(action.attrs.name, 10)
41 }, self.on_load_action);
45 //this.$element.find('a.oe-dashboard-action-rename').live('click', this.on_rename);
46 this.$element.find('.oe-dashboard-action').live('mouseover mouseout', function(event) {
47 $(this).find('.oe-dashboard-action-header .ui-icon, .oe-dashboard-action-header .oe-dashboard-action-rename').toggle(event.type == 'mouseover');
51 this.rpc('/web/view/undo_custom', {
52 view_id: this.view.fields_view.view_id
55 on_reset: function() {
56 this.rpc('/web/view/undo_custom', {
57 view_id: this.view.fields_view.view_id,
61 on_add_widget: function() {
63 var action_manager = new openerp.web.ActionManager(this);
64 var dialog = new openerp.web.Dialog(this, {
70 $(this).dialog('destroy');
73 self.do_add_widget(action_manager.inner_viewmanager.views.list.controller);
74 $(this).dialog('destroy');
78 action_manager.appendTo(dialog.$element);
79 action_manager.do_action({
80 res_model : 'ir.actions.actions',
81 views : [[false, 'list']],
82 type : 'ir.actions.act_window',
87 views_switcher : false,
88 action_buttons : false
91 // TODO: should bind ListView#select_record in order to catch record clicking
93 do_add_widget : function(listview) {
95 actions = listview.groups.get_selection().ids,
97 qdict = { view : this.view };
98 // TODO: should load multiple actions at once
99 _.each(actions, function(aid) {
100 self.rpc('/web/action/load', {
102 }, function(result) {
103 self.actions_attrs[aid] = {
105 string: _.trim(result.result.name)
108 attrs : self.actions_attrs[aid]
110 self.$element.find('.oe-dashboard-column:first').prepend(QWeb.render('DashBoard.action', qdict));
111 self.do_save_dashboard();
112 self.on_load_action(result)
116 on_rename : function(e) {
118 id = parseInt($(e.currentTarget).parents('.oe-dashboard-action:first').attr('data-id'), 10),
119 $header = $(e.currentTarget).parents('.oe-dashboard-action-header:first'),
120 $rename = $header.find('a.oe-dashboard-action-rename').hide(),
121 $title = $header.find('span.oe-dashboard-action-title').hide(),
122 $input = $header.find('input[name=title]');
123 $input.val($title.text()).show().focus().bind('keydown', function(e) {
124 if (e.which == 13 || e.which == 27) {
125 if (e.which == 13) { //enter
126 var val = $input.val();
131 self.actions_attrs[id].string = val;
132 self.do_save_dashboard();
134 $input.unbind('keydown').hide();
140 on_change_layout: function() {
143 current_layout : this.$element.find('.oe-dashboard').attr('data-layout')
145 var $dialog = $('<div>').dialog({
147 title: 'Edit Layout',
150 }).html(QWeb.render('DashBoard.layouts', qdict));
151 $dialog.find('li').click(function() {
152 var layout = $(this).attr('data-layout');
153 $dialog.dialog('destroy');
154 self.do_change_layout(layout);
157 do_change_layout: function(new_layout) {
158 var $dashboard = this.$element.find('.oe-dashboard');
159 var current_layout = $dashboard.attr('data-layout');
160 if (current_layout != new_layout) {
161 var clayout = current_layout.split('-').length,
162 nlayout = new_layout.split('-').length,
163 column_diff = clayout - nlayout;
164 if (column_diff > 0) {
165 var $last_column = $();
166 $dashboard.find('.oe-dashboard-column').each(function(k, v) {
168 $(v).find('.oe-dashboard-action').appendTo($last_column);
174 $dashboard.toggleClass('oe-dashboard-layout_' + current_layout + ' oe-dashboard-layout_' + new_layout);
175 $dashboard.attr('data-layout', new_layout);
176 this.do_save_dashboard();
179 on_fold_action: function(e) {
180 var $e = $(e.currentTarget),
181 $action = $e.parents('.oe-dashboard-action:first'),
182 id = parseInt($action.attr('data-id'), 10);
183 if ($e.is('.ui-icon-minusthick')) {
184 this.actions_attrs[id].fold = '1';
186 delete(this.actions_attrs[id].fold);
188 $e.toggleClass('ui-icon-minusthick ui-icon-plusthick');
189 $action.find('.oe-dashboard-action-content').toggle();
190 this.do_save_dashboard();
192 on_close_action: function(e) {
193 $(e.currentTarget).parents('.oe-dashboard-action:first').remove();
194 this.do_save_dashboard();
196 do_save_dashboard: function() {
199 form_title : this.view.fields_view.arch.attrs.string,
200 style : this.$element.find('.oe-dashboard').attr('data-layout'),
203 this.$element.find('.oe-dashboard-column').each(function() {
205 $(this).find('.oe-dashboard-action').each(function() {
206 var action_id = $(this).attr('data-id');
207 actions.push(self.actions_attrs[action_id]);
209 board.columns.push(actions);
211 var arch = QWeb.render('DashBoard.xml', board);
212 this.rpc('/web/view/add_custom', {
213 view_id: this.view.fields_view.view_id,
216 self.$element.find('.oe-dashboard-link-undo, .oe-dashboard-link-reset').show();
219 on_load_action: function(result) {
220 var action = result.result;
224 views_switcher : false,
225 action_buttons : false,
229 var am = new openerp.web.ActionManager(this);
230 this.action_managers.push(am);
231 am.appendTo($("#"+this.view.element_id + '_action_' + action.id));
232 am.do_action(action);
235 // We should start with three columns available
236 for (var i = this.node.children.length; i < 3; i++) {
237 this.node.children.push({
243 return QWeb.render(this.template, this);
245 do_reload: function() {
246 _.each(this.action_managers, function(am) {
249 this.action_managers = [];
254 openerp.web.form.DashBoardLegacy = openerp.web.form.DashBoard.extend({
256 if (this.node.tag == 'hpaned') {
257 this.node.attrs.style = '2-1';
258 } else if (this.node.tag == 'vpaned') {
259 this.node.attrs.style = '1';
261 this.node.tag = 'board';
262 _.each(this.node.children, function(child) {
263 if (child.tag.indexOf('child') == 0) {
264 child.tag = 'column';
265 var actions = [], first_child = child.children[0];
266 if (first_child && first_child.tag == 'vpaned') {
267 _.each(first_child.children, function(subchild) {
268 actions.push.apply(actions, subchild.children);
270 child.children = actions;
274 return this._super(this, arguments);
278 openerp.web.form.widgets.add('hpaned', 'openerp.web.form.DashBoardLegacy');
279 openerp.web.form.widgets.add('vpaned', 'openerp.web.form.DashBoardLegacy');
280 openerp.web.form.widgets.add('board', 'openerp.web.form.DashBoard');
282 openerp.web.client_actions.add(
283 'board.config.overview', 'openerp.web_dashboard.ConfigOverview'
285 if (!openerp.web_dashboard) {
287 openerp.web_dashboard = {};
289 openerp.web_dashboard.ConfigOverview = openerp.web.View.extend({
290 template: 'ConfigOverview',
291 init: function (parent) {
293 this.dataset = new openerp.web.DataSetSearch(
294 this, 'ir.actions.todo');
295 this.dataset.domain = [['type', '=', 'manual']];
299 $.when(this.dataset.read_slice(['state', 'action_id', 'category_id']),
300 this.dataset.call('progress'))
301 .then(this.on_records_loaded);
303 on_records_loaded: function (read_response, progress_response) {
304 var records = read_response[0].records,
305 progress = progress_response[0];
307 var grouped_todos = _(records).chain()
308 .map(function (record) {
311 name: record.action_id[1],
312 done: record.state !== 'open',
313 to_do: record.state === 'open',
314 category: record['category_id'][1] || "Uncategorized"
317 .groupBy(function (record) {return record.category})
319 this.$element.html(QWeb.render('ConfigOverview.content', {
320 completion: 100 * progress.done / progress.total,
321 groups: grouped_todos
323 var $progress = this.$element.find('div.oe-config-progress-bar');
324 $progress.progressbar({value: $progress.data('completion')});
327 this.$element.find('dl')
328 .delegate('input', 'click', function (e) {
329 // switch todo status
330 e.stopImmediatePropagation();
331 var new_state = this.checked ? 'done' : 'open',
332 todo_id = parseInt($(this).val(), 10);
333 self.dataset.write(todo_id, {state: new_state}, {}, function () {
337 .delegate('li:not(.oe-done)', 'click', function () {
338 self.widget_parent.widget_parent.widget_parent.do_execute_action({
340 name: 'action_launch'
342 $(this).data('id'), function () {
343 // after action popup closed, refresh configuration
351 openerp.web.client_actions.add(
352 'board.home.applications', 'openerp.web_dashboard.ApplicationTiles');
353 openerp.web_dashboard.ApplicationTiles = openerp.web.View.extend({
354 template: 'ApplicationTiles',
358 return new openerp.web.DataSetSearch(
359 this, 'ir.ui.menu', null, [['parent_id', '=', false]])
360 .read_slice( ['name', 'web_icon_data', 'web_icon_hover_data'], {}, function (applications) {
361 // Create a matrix of 3*x applications
363 while (applications.length) {
364 rows.push(applications.splice(0, 3));
368 'ApplicationTiles.content', {rows: rows}))
369 .find('.oe-dashboard-home-tile')
372 $this.closest('.openerp')
373 .find('.menu a[data-menu=' + $this.data('menuid') + ']')
378 openerp.web.client_actions.add(
379 'board.home.widgets', 'openerp.web_dashboard.Widget');
380 openerp.web_dashboard.Widget = openerp.web.View.extend(/** @lends openerp.web_dashboard.Widgets# */{
381 template: 'HomeWidget',
383 * Initializes a "HomeWidget" client widget: handles the display of a given
384 * res.widget objects in an OpenERP view (mainly a dashboard).
386 * @constructs openerp.web_dashboard.Widget
387 * @extends openerp.web.View
389 * @param {Object} parent
390 * @param {Object} options
391 * @param {Number} options.widget_id
393 init: function (parent, options) {
395 this.widget_id = options.widget_id;
399 return new openerp.web.DataSet(this, 'res.widget').read_ids(
400 [this.widget_id], ['title'], this.on_widget_loaded);
402 on_widget_loaded: function (widgets) {
403 var widget = widgets[0];
405 '/web_dashboard/widgets/content?session_id=%s&widget_id=%d',
406 this.session.session_id, widget.id);
407 this.$element.html(QWeb.render('HomeWidget.content', {