[imp] changed init of most views + the places were we init them
[odoo/odoo.git] / addons / web_dashboard / static / src / js / dashboard.js
1 openerp.web_dashboard = function(openerp) {
2 var QWeb = openerp.web.qweb;
3 QWeb.add_template('/web_dashboard/static/src/xml/web_dashboard.xml');
4
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 = [];
11     },
12     start: function() {
13         var self = this;
14         this._super.apply(this, arguments);
15
16         this.$element.find('.oe-dashboard-column').sortable({
17             connectWith: '.oe-dashboard-column',
18             handle: '.oe-dashboard-action-header',
19             scroll: false
20         }).disableSelection().bind('sortstop', self.do_save_dashboard);
21
22         // Events
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);
27
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);
30
31         this.actions_attrs = {};
32         // Init actions
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);
42             });
43         });
44
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');
48         });
49     },
50     on_undo: function() {
51         this.rpc('/web/view/undo_custom', {
52             view_id: this.view.fields_view.view_id
53         }, this.do_reload);
54     },
55     on_reset: function() {
56         this.rpc('/web/view/undo_custom', {
57             view_id: this.view.fields_view.view_id,
58             reset: true
59         }, this.do_reload);
60     },
61     on_add_widget: function() {
62         var self = this;
63         var action_manager = new openerp.web.ActionManager(this);
64         var dialog = new openerp.web.Dialog(this, {
65             title : 'Actions',
66             width: 800,
67             height: 600,
68             buttons : {
69                 Cancel : function() {
70                     $(this).dialog('destroy');
71                 },
72                 Add : function() {
73                     self.do_add_widget(action_manager.inner_viewmanager.views.list.controller);
74                     $(this).dialog('destroy');
75                 }
76             }
77         }).start().open();
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',
83             limit : 80,
84             auto_search : true,
85             flags : {
86                 sidebar : false,
87                 views_switcher : false,
88                 action_buttons : false
89             }
90         });
91         // TODO: should bind ListView#select_record in order to catch record clicking
92     },
93     do_add_widget : function(listview) {
94         var self = this,
95             actions = listview.groups.get_selection().ids,
96             results = [],
97             qdict = { view : this.view };
98         // TODO: should load multiple actions at once
99         _.each(actions, function(aid) {
100             self.rpc('/web/action/load', {
101                 action_id: aid
102             }, function(result) {
103                 self.actions_attrs[aid] = {
104                     name: aid,
105                     string: _.trim(result.result.name)
106                 };
107                 qdict.action = {
108                     attrs : self.actions_attrs[aid]
109                 };
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)
113             });
114         });
115     },
116     on_rename : function(e) {
117         var self = this,
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();
127                     if (!val) {
128                         return false;
129                     }
130                     $title.text(val);
131                     self.actions_attrs[id].string = val;
132                     self.do_save_dashboard();
133                 }
134                 $input.unbind('keydown').hide();
135                 $rename.show();
136                 $title.show();
137             }
138         });
139     },
140     on_change_layout: function() {
141         var self = this;
142         var qdict = {
143             current_layout : this.$element.find('.oe-dashboard').attr('data-layout')
144         };
145         var $dialog = $('<div>').dialog({
146                             modal: true,
147                             title: 'Edit Layout',
148                             width: 'auto',
149                             height: 'auto'
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);
155         });
156     },
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) {
167                     if (k >= nlayout) {
168                         $(v).find('.oe-dashboard-action').appendTo($last_column);
169                     } else {
170                         $last_column = $(v);
171                     }
172                 });
173             }
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();
177         }
178     },
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';
185         } else {
186             delete(this.actions_attrs[id].fold);
187         }
188         $e.toggleClass('ui-icon-minusthick ui-icon-plusthick');
189         $action.find('.oe-dashboard-action-content').toggle();
190         this.do_save_dashboard();
191     },
192     on_close_action: function(e) {
193         $(e.currentTarget).parents('.oe-dashboard-action:first').remove();
194         this.do_save_dashboard();
195     },
196     do_save_dashboard: function() {
197         var self = this;
198         var board = {
199                 form_title : this.view.fields_view.arch.attrs.string,
200                 style : this.$element.find('.oe-dashboard').attr('data-layout'),
201                 columns : []
202             };
203         this.$element.find('.oe-dashboard-column').each(function() {
204             var actions = [];
205             $(this).find('.oe-dashboard-action').each(function() {
206                 var action_id = $(this).attr('data-id');
207                 actions.push(self.actions_attrs[action_id]);
208             });
209             board.columns.push(actions);
210         });
211         var arch = QWeb.render('DashBoard.xml', board);
212         this.rpc('/web/view/add_custom', {
213             view_id: this.view.fields_view.view_id,
214             arch: arch
215         }, function() {
216             self.$element.find('.oe-dashboard-link-undo, .oe-dashboard-link-reset').show();
217         });
218     },
219     on_load_action: function(result) {
220         var action = result.result;
221         action.flags = {
222             search_view : false,
223             sidebar : false,
224             views_switcher : false,
225             action_buttons : false,
226             pager: false,
227             low_profile: true
228         };
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);
233     },
234     render: function() {
235         // We should start with three columns available
236         for (var i = this.node.children.length; i < 3; i++) {
237             this.node.children.push({
238                 tag: 'column',
239                 attrs: {},
240                 children: []
241             });
242         }
243         return QWeb.render(this.template, this);
244     },
245     do_reload: function() {
246         _.each(this.action_managers, function(am) {
247             am.stop();
248         });
249         this.action_managers = [];
250         this.view.stop();
251         this.view.start();
252     }
253 });
254 openerp.web.form.DashBoardLegacy = openerp.web.form.DashBoard.extend({
255     render: function() {
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';
260         }
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);
269                     });
270                     child.children = actions;
271                 }
272             }
273         });
274         return this._super(this, arguments);
275     }
276 });
277
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');
281
282 openerp.web.client_actions.add(
283     'board.config.overview', 'openerp.web_dashboard.ConfigOverview'
284 );
285 if (!openerp.web_dashboard) {
286     /** @namespace */
287     openerp.web_dashboard = {};
288 }
289 openerp.web_dashboard.ConfigOverview = openerp.web.View.extend({
290     template: 'ConfigOverview',
291     init: function (parent) {
292         this._super(parent);
293         this.dataset = new openerp.web.DataSetSearch(
294                 this, 'ir.actions.todo');
295         this.dataset.domain = [['type', '=', 'manual']];
296     },
297     start: function () {
298         this._super();
299         $.when(this.dataset.read_slice(['state', 'action_id', 'category_id']),
300                this.dataset.call('progress'))
301             .then(this.on_records_loaded);
302     },
303     on_records_loaded: function (read_response, progress_response) {
304         var records = read_response[0].records,
305            progress = progress_response[0];
306
307         var grouped_todos = _(records).chain()
308             .map(function (record) {
309                 return {
310                     id: record.id,
311                     name: record.action_id[1],
312                     done: record.state !== 'open',
313                     to_do: record.state === 'open',
314                     category: record['category_id'][1] || "Uncategorized"
315                 }
316             })
317             .groupBy(function (record) {return record.category})
318             .value();
319         this.$element.html(QWeb.render('ConfigOverview.content', {
320             completion: 100 * progress.done / progress.total,
321             groups: grouped_todos
322         }));
323         var $progress = this.$element.find('div.oe-config-progress-bar');
324         $progress.progressbar({value: $progress.data('completion')});
325
326         var self = this;
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 () {
334                     self.start();
335                 });
336             })
337             .delegate('li:not(.oe-done)', 'click', function () {
338                 self.widget_parent.widget_parent.widget_parent.do_execute_action({
339                         type: 'object',
340                         name: 'action_launch'
341                     }, self.dataset,
342                     $(this).data('id'), function () {
343                         // after action popup closed, refresh configuration
344                         // thingie
345                         self.start();
346                     });
347             });
348     }
349 });
350
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',
355     start: function () {
356         this._super();
357         var self = this;
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
362                 var rows = [];
363                 while (applications.length) {
364                     rows.push(applications.splice(0, 3));
365                 }
366                 self.$element
367                     .append(QWeb.render(
368                         'ApplicationTiles.content', {rows: rows}))
369                     .find('.oe-dashboard-home-tile')
370                         .click(function () {
371                             var $this = $(this);
372                             $this.closest('.openerp')
373                                  .find('.menu a[data-menu=' + $this.data('menuid') + ']')
374                                  .click();});
375             });
376     }
377 });
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',
382     /**
383      * Initializes a "HomeWidget" client widget: handles the display of a given
384      * res.widget objects in an OpenERP view (mainly a dashboard).
385      *
386      * @constructs openerp.web_dashboard.Widget
387      * @extends openerp.web.View
388      *
389      * @param {Object} parent
390      * @param {Object} options
391      * @param {Number} options.widget_id
392      */
393     init: function (parent, options) {
394         this._super(parent);
395         this.widget_id = options.widget_id;
396     },
397     start: function () {
398         this._super();
399         return new openerp.web.DataSet(this, 'res.widget').read_ids(
400                 [this.widget_id], ['title'], this.on_widget_loaded);
401     },
402     on_widget_loaded: function (widgets) {
403         var widget = widgets[0];
404         var url = _.sprintf(
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', {
408             widget: widget,
409             url: url
410         }));
411     }
412 });
413 };