1 openerp.base_dashboard = function(openerp) {
3 QWeb.add_template('/base_dashboard/static/src/xml/base_dashboard.xml');
5 openerp.base.form.DashBoard = openerp.base.form.Widget.extend({
6 init: function(view, node) {
7 this._super(view, node);
8 this.template = 'DashBoard';
9 this.actions_attrs = {};
13 this._super.apply(this, arguments);
15 this.$element.find('.oe-dashboard-column').sortable({
16 connectWith: '.oe-dashboard-column',
17 handle: '.oe-dashboard-action-header',
19 }).disableSelection().bind('sortstop', self.do_save_dashboard);
22 this.$element.find('.oe-dashboard-link-undo').click(this.on_undo);
23 this.$element.find('.oe-dashboard-link-reset').click(this.on_reset);
24 this.$element.find('.oe-dashboard-link-add_widget').click(this.on_add_widget);
25 this.$element.find('.oe-dashboard-link-change_layout').click(this.on_change_layout);
26 this.$element.find('.oe-dashboard-column .oe-dashboard-fold').click(this.on_fold_action);
27 this.$element.find('.oe-dashboard-column .ui-icon-closethick').click(this.on_close_action);
29 this.actions_attrs = {};
31 _.each(this.node.children, function(column) {
32 _.each(column.children, function(action) {
33 delete(action.attrs.width);
34 delete(action.attrs.height);
35 delete(action.attrs.colspan);
36 self.actions_attrs[action.attrs.name] = action.attrs;
37 self.rpc('/base/action/load', {
38 action_id: parseInt(action.attrs.name, 10)
39 }, self.on_load_action);
43 this.$element.find('a.oe-dashboard-action-rename').live('click', this.on_rename);
46 this.rpc('/base/view/undo_custom', {
47 view_id: this.view.fields_view.view_id
50 on_reset: function() {
51 this.rpc('/base/view/undo_custom', {
52 view_id: this.view.fields_view.view_id,
56 on_add_widget: function() {
59 res_model : 'ir.actions.actions',
60 views : [[false, 'list']],
61 type : 'ir.actions.act_window',
66 views_switcher : false,
67 action_buttons : false
70 // TODO: create a Dialog controller which optionally takes an action
71 // Should set width & height automatically and take buttons & views callback
72 var dialog_id = _.uniqueId('act_window_dialog');
73 var action_manager = new openerp.base.ActionManager(this.session, dialog_id);
74 var $dialog = $('<div id=' + dialog_id + '>').dialog({
81 $(this).dialog('destroy');
84 self.do_add_widget(action_manager);
85 $(this).dialog('destroy');
89 action_manager.start();
90 action_manager.do_action(action);
91 // TODO: should bind ListView#select_record in order to catch record clicking
93 do_add_widget : function(action_manager) {
95 actions = action_manager.viewmanager.views.list.controller.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('/base/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('/base/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,
228 new openerp.base.ActionManager(
229 this.session, this.view.element_id + '_action_' + action.id)
233 // We should start with three columns available
234 for (var i = this.node.children.length; i < 3; i++) {
235 this.node.children.push({
241 return QWeb.render(this.template, this);
243 do_reload: function() {
244 this.view.view_manager.stop();
245 this.view.view_manager.start();
248 openerp.base.form.DashBoardLegacy = openerp.base.form.DashBoard.extend({
250 if (this.node.tag == 'hpaned') {
251 this.node.attrs.style = '1-1';
252 } else if (this.node.tag == 'vpaned') {
253 this.node.attrs.style = '1';
255 this.node.tag = 'board';
256 _.each(this.node.children, function(child) {
257 if (child.tag.indexOf('child') == 0) {
258 child.tag = 'column';
259 var actions = [], first_child = child.children[0];
260 if (first_child && first_child.tag == 'vpaned') {
261 _.each(first_child.children, function(subchild) {
262 actions.push.apply(actions, subchild.children);
264 child.children = actions;
268 return this._super(this, arguments);
272 openerp.base.form.widgets.add('hpaned', 'openerp.base.form.DashBoardLegacy');
273 openerp.base.form.widgets.add('vpaned', 'openerp.base.form.DashBoardLegacy');
274 openerp.base.form.widgets.add('board', 'openerp.base.form.DashBoard');
276 openerp.base.client_actions.add(
277 'board.config.overview', 'openerp.base_dashboard.ConfigOverview'
279 if (!openerp.base_dashboard) {
280 openerp.base_dashboard = {};
282 openerp.base_dashboard.ConfigOverview = openerp.base.View.extend({
283 init: function (parent_or_session, element_id) {
284 this._super(parent_or_session, element_id);
285 this.dataset = new openerp.base.DataSetSearch(
286 this.session, 'ir.actions.todo');
289 this.dataset.read_slice(['state', 'action_id'], undefined, undefined,
290 this.on_records_loaded);
292 on_records_loaded: function (records) {
294 done_records = _(records).filter(function (record) {
295 return record.state === 'done';}),
296 done_ratio = done_records.length / records.length;
297 this.$element.html(QWeb.render('ConfigOverview', {
298 completion: done_ratio * 100,
299 todos: _(records).map(function (record) {
301 action: record.action_id[0],
302 name: record.action_id[1],
304 done: record.state === 'done',
305 skipped: record.state === 'skip',
306 to_do: (record.state !== 'done' && record.state !== 'skip')
310 var $progress = this.$element.find('div.oe-config-progress');
311 $progress.progressbar({value: $progress.data('completion')});
313 // allow for executing to-do and skipped action
314 this.$element.find('div.oe-dashboard-config-overview ul')
315 .delegate('li.ui-state-error', 'click', function () {
316 self.execute_action({
318 name: $(this).data('action')
320 new openerp.base.ActionManager(self.session, self.element_id),
321 null, null, function () {
322 // after action popup closed, refresh configuration thingie
329 openerp.base.client_actions.add(
330 'board.home.applications', 'openerp.base_dashboard.ApplicationTiles');
331 openerp.base_dashboard.ApplicationTiles = openerp.base.View.extend({
332 init: function (parent_or_session, element_id) {
333 this._super(parent_or_session, element_id);
334 this.dataset = new openerp.base.DataSetSearch(
335 this.session, 'ir.ui.menu', null, [['parent_id', '=', false]]);
339 this.dataset.read_slice(
340 ['name', 'web_icon_data', 'web_icon_hover_data'],
341 null, null, function (applications) {
342 // Create a matrix of 3*x applications
344 while (applications.length) {
345 rows.push(applications.splice(0, 3));
349 'ApplicationTiles', {rows: rows}))
350 .find('.oe-dashboard-home-tile')
353 $this.closest('.openerp')
354 .find('.menu a[data-menu=' + $this.data('menuid') + ']')
359 openerp.base.client_actions.add(
360 'board.home.widgets', 'openerp.base_dashboard.Widgets');
361 openerp.base_dashboard.Widgets = openerp.base.View.extend({
362 init: function (parent_or_session, element_id) {
363 this._super(parent_or_session, element_id);
364 this.user_widgets = new openerp.base.DataSetSearch(
365 this.session, 'res.widget.user', null,
366 ['|', ['user_id', '=', false],
367 ['user_id', '=', this.session.uid]]);
368 this.widgets = new openerp.base.DataSetSearch(this.session, 'res.widget');
371 this.user_widgets.read_slice(['widget_id', 'user_id'], null, null,
372 this.on_widgets_list_loaded);
374 on_widgets_list_loaded: function (user_widgets) {
376 var widget_user = {};
377 _(user_widgets).each(function (widget) {
378 widget['widget_id'] = widget['widget_id'][0];
379 widget_user[widget['widget_id']] = {
380 removable: widget['user_id'] !== false,
381 user_widget_id: widget['id']
384 this.widgets.read_ids(_(user_widgets).pluck('widget_id'), [], function (widgets) {
385 _(widgets).each(function (widget) {
386 _.extend(widget, widget_user[widget['id']]);
388 var root = self.$element[0];
389 root.innerHTML = QWeb.render('HomeWidgets', {
393 self.process_widgets_scripts(0, root.getElementsByTagName('script'));
396 process_widgets_scripts: function (index, nodes) {
397 if (nodes.length <= index) {
400 var old_write = window.document.write,
402 script = nodes[index],
403 deferred = $.Deferred().then(function () {
404 window.document.write = old_write; }),
405 continuation = function () {
406 $.when(self.process_widgets_scripts(index+1, nodes)).then(
409 window.document.write = function (s) {
410 $(script).closest('.oe-dashboard-home-widgets-widget')
416 new Function(script.firstChild.nodeValue)();
417 setTimeout(continuation);
419 $LAB.script(script.src).wait(continuation);