[IMP] width of dialogs
[odoo/odoo.git] / addons / web_dashboard / static / src / js / dashboard.js
1 openerp.web_dashboard = function(instance) {
2 var QWeb = instance.web.qweb,
3     _t = instance.web._t;
4
5 if (!instance.web_dashboard) {
6     /** @namespace */
7     instance.web_dashboard = {};
8 }
9
10 instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
11     init: function(view, node) {
12         this._super(view, node);
13         this.form_template = 'DashBoard';
14         this.actions_attrs = {};
15         this.action_managers = [];
16     },
17     start: function() {
18         var self = this;
19         this._super.apply(this, arguments);
20
21         this.$element.find('.oe_dashboard_column').sortable({
22             connectWith: '.oe_dashboard_column',
23             handle: '.oe_dashboard_action_header',
24             scroll: false
25         }).disableSelection().bind('sortstop', self.do_save_dashboard);
26
27         // Events
28         this.$element.find('.oe_dashboard_link_reset').click(this.on_reset);
29         this.$element.find('.oe_dashboard_link_change_layout').click(this.on_change_layout);
30
31         this.$element.delegate('.oe_dashboard_column .oe_dashboard_fold', 'click', this.on_fold_action);
32         this.$element.delegate('.oe_dashboard_column .ui-icon-closethick', 'click', this.on_close_action);
33
34         // Init actions
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.rpc('/web/action/load', {
41                     action_id: parseInt(action.attrs.name, 10)
42                 }, function(result) {
43                     self.on_load_action(result, column_index + '_' + action_index, action.attrs);
44                 });
45             });
46         });
47     },
48     on_reset: function() {
49         this.rpc('/web/view/undo_custom', {
50             view_id: this.view.fields_view.view_id,
51             reset: true
52         }, this.do_reload);
53     },
54     on_change_layout: function() {
55         var self = this;
56         var qdict = {
57             current_layout : this.$element.find('.oe_dashboard').attr('data-layout')
58         };
59         var $dialog = instance.web.dialog($('<div>'), {
60                             modal: true,
61                             title: _t("Edit Layout"),
62                             width: 'auto',
63                             height: 'auto'
64                         }).html(QWeb.render('DashBoard.layouts', qdict));
65         $dialog.find('li').click(function() {
66             var layout = $(this).attr('data-layout');
67             $dialog.dialog('destroy');
68             self.do_change_layout(layout);
69         });
70     },
71     do_change_layout: function(new_layout) {
72         var $dashboard = this.$element.find('.oe_dashboard');
73         var current_layout = $dashboard.attr('data-layout');
74         if (current_layout != new_layout) {
75             var clayout = current_layout.split('-').length,
76                 nlayout = new_layout.split('-').length,
77                 column_diff = clayout - nlayout;
78             if (column_diff > 0) {
79                 var $last_column = $();
80                 $dashboard.find('.oe_dashboard_column').each(function(k, v) {
81                     if (k >= nlayout) {
82                         $(v).find('.oe_dashboard_action').appendTo($last_column);
83                     } else {
84                         $last_column = $(v);
85                     }
86                 });
87             }
88             $dashboard.toggleClass('oe_dashboard_layout_' + current_layout + ' oe_dashboard_layout_' + new_layout);
89             $dashboard.attr('data-layout', new_layout);
90             this.do_save_dashboard();
91         }
92     },
93     on_fold_action: function(e) {
94         var $e = $(e.currentTarget),
95             $action = $e.parents('.oe_dashboard_action:first'),
96             id = parseInt($action.attr('data-id'), 10);
97         if ($e.is('.ui-icon-minusthick')) {
98             $action.data('action_attrs').fold = '1';
99         } else {
100             delete($action.data('action_attrs').fold);
101         }
102         $e.toggleClass('ui-icon-minusthick ui-icon-plusthick');
103         $action.find('.oe_dashboard_action_content').toggle();
104         this.do_save_dashboard();
105     },
106     on_close_action: function(e) {
107         if (confirm(_t("Are you sure you want to remove this item ?"))) {
108             $(e.currentTarget).parents('.oe_dashboard_action:first').remove();
109             this.do_save_dashboard();
110         }
111     },
112     do_save_dashboard: function() {
113         var self = this;
114         var board = {
115                 form_title : this.view.fields_view.arch.attrs.string,
116                 style : this.$element.find('.oe_dashboard').attr('data-layout'),
117                 columns : []
118             };
119         this.$element.find('.oe_dashboard_column').each(function() {
120             var actions = [];
121             $(this).find('.oe_dashboard_action').each(function() {
122                 var action_id = $(this).attr('data-id'),
123                     new_attrs = _.clone($(this).data('action_attrs'));
124                 if (new_attrs.domain) {
125                     new_attrs.domain = new_attrs.domain_string;
126                     delete(new_attrs.domain_string);
127                 }
128                 if (new_attrs.context) {
129                     new_attrs.context = new_attrs.context_string;
130                     delete(new_attrs.context_string);
131                 }
132                 actions.push(new_attrs);
133             });
134             board.columns.push(actions);
135         });
136         var arch = QWeb.render('DashBoard.xml', board);
137         this.rpc('/web/view/add_custom', {
138             view_id: this.view.fields_view.view_id,
139             arch: arch
140         }, function() {
141             self.$element.find('.oe_dashboard_link_reset').show();
142         });
143     },
144     on_load_action: function(result, index, action_attrs) {
145         var self = this,
146             action = result.result,
147             view_mode = action_attrs.view_mode;
148
149         if (action_attrs.context && action_attrs.context['dashboard_merge_domains_contexts'] === false) {
150             // TODO: replace this 6.1 workaround by attribute on <action/>
151             action.context = action_attrs.context || {};
152             action.domain = action_attrs.domain || [];
153         } else {
154             if (action_attrs.context) {
155                 action.context = _.extend((action.context || {}), action_attrs.context);
156             }
157             if (action_attrs.domain) {
158                 action.domain = action.domain || [];
159                 action.domain.unshift.apply(action.domain, action_attrs.domain);
160             }
161         }
162
163         var action_orig = _.extend({ flags : {} }, action);
164
165         if (view_mode && view_mode != action.view_mode) {
166             action.views = _.map(view_mode.split(','), function(mode) {
167                 mode = mode === 'tree' ? 'list' : mode;
168                 return _(action.views).find(function(view) { return view[1] == mode; })
169                     || [false, mode];
170             });
171         }
172
173         action.flags = {
174             search_view : false,
175             sidebar : false,
176             views_switcher : false,
177             action_buttons : false,
178             pager: false,
179             low_profile: true,
180             display_title: false,
181             list: {
182                 selectable: false
183             }
184         };
185         var am = new instance.web.ActionManager(this),
186             // FIXME: ideally the dashboard view shall be refactored like kanban.
187             $action = $('#' + this.view.element_id + '_action_' + index);
188         $action.parent().data('action_attrs', action_attrs);
189         this.action_managers.push(am);
190         am.appendTo($action);
191         am.do_action(action);
192         am.do_action = function (action) {
193             self.do_action(action);
194         };
195         if (action_attrs.creatable && action_attrs.creatable !== 'false') {
196             var action_id = parseInt(action_attrs.creatable, 10);
197             $action.parent().find('button.oe_dashboard_button_create').click(function() {
198                 if (isNaN(action_id)) {
199                     action_orig.flags.default_view = 'form';
200                     self.do_action(action_orig);
201                 } else {
202                     self.rpc('/web/action/load', {
203                         action_id: action_id
204                     }, function(result) {
205                         result.result.flags = result.result.flags || {};
206                         result.result.flags.default_view = 'form';
207                         self.do_action(result.result);
208                     });
209                 }
210             });
211         }
212         if (am.inner_viewmanager) {
213             am.inner_viewmanager.on_mode_switch.add(function(mode) {
214                 var new_views = [];
215                 _.each(action_orig.views, function(view) {
216                     new_views[view[1] === mode ? 'unshift' : 'push'](view);
217                 });
218                 if (!new_views.length || new_views[0][1] !== mode) {
219                     new_views.unshift([false, mode]);
220                 }
221                 action_orig.views = new_views;
222                 action_orig.res_id = am.inner_viewmanager.dataset.ids[am.inner_viewmanager.dataset.index];
223                 self.do_action(action_orig);
224             });
225         }
226     },
227     renderElement: function() {
228         var check = _.detect(this.node.children, function(column, column_index) {
229             return _.detect(column.children,function(element){
230                 return element.tag === "action"? element: false;
231             });
232         });
233         if (!check) {
234             return this.no_result();
235         }
236         // We should start with three columns available
237         for (var i = this.node.children.length; i < 3; i++) {
238             this.node.children.push({
239                 tag: 'column',
240                 attrs: {},
241                 children: []
242             });
243         }
244         var rendered = QWeb.render(this.form_template, this);
245         this.$element.html(rendered);
246     },
247     no_result: function() {
248         if (this.view.options.action.help) {
249             this.$element.append(
250                 $('<div class="oe_view_nocontent">')
251                     .append($('<img>', { src: '/web_dashboard/static/src/img/view_todo_arrow.png' }))
252                     .append($('<div>').html(this.view.options.action.help || " "))
253             );
254         }
255     },
256     do_reload: function() {
257         var view_manager = this.view.getParent(),
258             action_manager = view_manager.getParent();
259         this.view.destroy();
260         action_manager.do_action(view_manager.action);
261     }
262 });
263 instance.web.form.DashBoardLegacy = instance.web.form.DashBoard.extend({
264     renderElement: function() {
265         if (this.node.tag == 'hpaned') {
266             this.node.attrs.style = '2-1';
267         } else if (this.node.tag == 'vpaned') {
268             this.node.attrs.style = '1';
269         }
270         this.node.tag = 'board';
271         _.each(this.node.children, function(child) {
272             if (child.tag.indexOf('child') == 0) {
273                 child.tag = 'column';
274                 var actions = [], first_child = child.children[0];
275                 if (first_child && first_child.tag == 'vpaned') {
276                     _.each(first_child.children, function(subchild) {
277                         actions.push.apply(actions, subchild.children);
278                     });
279                     child.children = actions;
280                 }
281             }
282         });
283         this._super(this);
284     }
285 });
286
287 instance.web.form.tags.add('hpaned', 'instance.web.form.DashBoardLegacy');
288 instance.web.form.tags.add('vpaned', 'instance.web.form.DashBoardLegacy');
289 instance.web.form.tags.add('board', 'instance.web.form.DashBoard');
290
291 /*
292  * Widgets
293  * This client action designed to be used as a dashboard widget display
294  * the html content of a res_widget given as argument
295  */
296 instance.web.client_actions.add( 'board.home.widgets', 'instance.web_dashboard.Widget');
297 instance.web_dashboard.Widget = instance.web.View.extend(/** @lends instance.web_dashboard.Widgets# */{
298     template: 'HomeWidget',
299     /**
300      * Initializes a "HomeWidget" client widget: handles the display of a given
301      * res.widget objects in an OpenERP view (mainly a dashboard).
302      *
303      * @constructs instance.web_dashboard.Widget
304      * @extends instance.web.View
305      *
306      * @param {Object} parent
307      * @param {Object} options
308      * @param {Number} options.widget_id
309      */
310     init: function (parent, options) {
311         this._super(parent);
312         this.widget_id = options.widget_id;
313     },
314     start: function () {
315         var ds = new instance.web.DataSet(this, 'res.widget');
316         return ds.read_ids([this.widget_id], ['title']).then(this.on_widget_loaded);
317     },
318     on_widget_loaded: function (widgets) {
319         var widget = widgets[0];
320         var url = _.str.sprintf(
321             '/web_dashboard/widgets/content?session_id=%s&widget_id=%d',
322             this.session.session_id, widget.id);
323         this.$element.html(QWeb.render('HomeWidget.content', {
324             widget: widget,
325             url: url
326         }));
327     }
328 });
329
330
331 };