1 openerp.board = function(instance) {
2 var QWeb = instance.web.qweb,
10 instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
12 'click .oe_dashboard_link_reset': 'on_reset',
13 'click .oe_dashboard_link_change_layout': 'on_change_layout',
14 'click h2.oe_header span.oe_header_txt': function (ev) {
15 if(ev.target === ev.currentTarget)
16 self.on_header_string($(ev.target).parent());
18 'click .oe_dashboard_column .oe_fold': 'on_fold_action',
19 'click .oe_dashboard_column .oe_close': 'on_close_action',
21 init: function(view, node) {
22 this._super(view, node);
23 this.form_template = 'DashBoard';
24 this.actions_attrs = {};
25 this.action_managers = [];
29 this._super.apply(this, arguments);
31 this.$('.oe_dashboard_column').sortable({
32 connectWith: '.oe_dashboard_column',
35 }).bind('sortstop', self.do_save_dashboard);
37 var old_title = this.__parentedParent.get('title');
38 this.__parentedParent.on('load_record', self, function(){
39 self.__parentedParent.set({ 'title': old_title});
43 _.each(this.node.children, function(column, column_index) {
44 _.each(column.children, function(action, action_index) {
45 delete(action.attrs.width);
46 delete(action.attrs.height);
47 delete(action.attrs.colspan);
48 var action_id = _.str.toNumber(action.attrs.name);
49 if (!_.isNaN(action_id)) {
50 self.rpc('/web/action/load', {action_id: action_id}).done(function(result) {
51 self.on_load_action(result, column_index + '_' + action_index, action.attrs);
57 on_header_string:function(h2){
59 var span = h2.find('span:first').hide();
60 var input = h2.find('.oe_header_text').css('visibility','visible');
61 var attr = h2.closest(".oe_action").data('action_attrs');
62 var change_string = function(new_name){
63 attr['string'] = new_name;
64 span.text(new_name).show();
65 input.css('visibility','hidden');
66 self.do_save_dashboard();
70 .change(function(event){
71 change_string($(this).val());
73 .keyup(function(event){
74 if(event.keyCode == 27){
75 //esc key to cancel changes
76 input.css('visibility','hidden');
81 on_reset: function() {
82 this.rpc('/web/view/undo_custom', {
83 view_id: this.view.fields_view.view_id,
85 }).done(this.do_reload);
87 on_change_layout: function() {
90 current_layout : this.$el.find('.oe_dashboard').attr('data-layout')
92 var $dialog = new instance.web.Dialog(this, {
93 title: _t("Edit Layout"),
94 }, QWeb.render('DashBoard.layouts', qdict)).open();
95 $dialog.$el.find('li').click(function() {
96 var layout = $(this).attr('data-layout');
97 self.do_change_layout(layout);
98 $dialog.$dialog_box.modal('hide');
101 do_change_layout: function(new_layout) {
102 var $dashboard = this.$el.find('.oe_dashboard');
103 var current_layout = $dashboard.attr('data-layout');
104 if (current_layout != new_layout) {
105 var clayout = current_layout.split('-').length,
106 nlayout = new_layout.split('-').length,
107 column_diff = clayout - nlayout;
108 if (column_diff > 0) {
109 var $last_column = $();
110 $dashboard.find('.oe_dashboard_column').each(function(k, v) {
112 $(v).find('.oe_action').appendTo($last_column);
118 $dashboard.toggleClass('oe_dashboard_layout_' + current_layout + ' oe_dashboard_layout_' + new_layout);
119 $dashboard.attr('data-layout', new_layout);
120 this.do_save_dashboard();
123 on_fold_action: function(e) {
124 var $e = $(e.currentTarget),
125 $action = $e.parents('.oe_action:first'),
126 id = parseInt($action.attr('data-id'), 10);
127 if ($e.is('.oe_minimize')) {
128 $action.data('action_attrs').fold = '1';
130 delete($action.data('action_attrs').fold);
132 $e.toggleClass('oe_minimize oe_maximize');
133 $action.find('.oe_content').toggle();
134 this.do_save_dashboard();
136 on_close_action: function(e) {
137 if (confirm(_t("Are you sure you want to remove this item ?"))) {
138 $(e.currentTarget).parents('.oe_action:first').remove();
139 this.do_save_dashboard();
142 do_save_dashboard: function() {
145 form_title : this.view.fields_view.arch.attrs.string,
146 style : this.$el.find('.oe_dashboard').attr('data-layout'),
149 this.$el.find('.oe_dashboard_column').each(function() {
151 $(this).find('.oe_action').each(function() {
152 var action_id = $(this).attr('data-id'),
153 new_attrs = _.clone($(this).data('action_attrs'));
154 if (new_attrs.domain) {
155 new_attrs.domain = new_attrs.domain_string;
156 delete(new_attrs.domain_string);
158 if (new_attrs.context) {
159 new_attrs.context = new_attrs.context_string;
160 delete(new_attrs.context_string);
162 actions.push(new_attrs);
164 board.columns.push(actions);
166 var arch = QWeb.render('DashBoard.xml', board);
167 this.rpc('/web/view/add_custom', {
168 view_id: this.view.fields_view.view_id,
172 on_load_action: function(result, index, action_attrs) {
175 view_mode = action_attrs.view_mode;
177 // evaluate action_attrs context and domain
178 action_attrs.context_string = action_attrs.context;
179 action_attrs.context = instance.web.pyeval.eval(
180 'context', action_attrs.context || {});
181 action_attrs.domain_string = action_attrs.domain;
182 action_attrs.domain = instance.web.pyeval.eval(
183 'domain', action_attrs.domain || [], action_attrs.context);
184 if (action_attrs.context['dashboard_merge_domains_contexts'] === false) {
185 // TODO: replace this 6.1 workaround by attribute on <action/>
186 action.context = action_attrs.context || {};
187 action.domain = action_attrs.domain || [];
189 action.context = instance.web.pyeval.eval(
190 'contexts', [action.context || {}, action_attrs.context]);
191 action.domain = instance.web.pyeval.eval(
192 'domains', [action_attrs.domain, action.domain || []],
196 var action_orig = _.extend({ flags : {} }, action);
198 if (view_mode && view_mode != action.view_mode) {
199 action.views = _.map(view_mode.split(','), function(mode) {
200 mode = mode === 'tree' ? 'list' : mode;
201 return _(action.views).find(function(view) { return view[1] == mode; })
209 views_switcher : false,
210 action_buttons : false,
214 display_title: false,
219 var am = new instance.web.ActionManager(this),
220 // FIXME: ideally the dashboard view shall be refactored like kanban.
221 $action = $('#' + this.view.element_id + '_action_' + index);
222 $action.parent().data('action_attrs', action_attrs);
223 this.action_managers.push(am);
224 am.appendTo($action);
225 am.do_action(action);
226 am.do_action = function (action) {
227 self.do_action(action);
229 if (am.inner_widget) {
230 var new_form_action = function(id, editable) {
232 _.each(action_orig.views, function(view) {
233 new_views[view[1] === 'form' ? 'unshift' : 'push'](view);
235 if (!new_views.length || new_views[0][1] !== 'form') {
236 new_views.unshift([false, 'form']);
238 action_orig.views = new_views;
239 action_orig.res_id = id;
240 action_orig.flags = {
242 "initial_mode": editable ? "edit" : "view",
245 self.do_action(action_orig);
247 var list = am.inner_widget.views.list;
249 list.created.done(function() {
250 $(list.controller.groups).off('row_link').on('row_link', function(e, id) {
255 var kanban = am.inner_widget.views.kanban;
257 kanban.created.done(function() {
258 kanban.controller.open_record = function(id, editable) {
259 new_form_action(id, editable);
265 renderElement: function() {
268 var check = _.detect(this.node.children, function(column, column_index) {
269 return _.detect(column.children,function(element){
270 return element.tag === "action"? element: false;
274 return this.no_result();
276 // We should start with three columns available
277 for (var i = this.node.children.length; i < 3; i++) {
278 this.node.children.push({
284 var rendered = QWeb.render(this.form_template, this);
285 this.$el.html(rendered);
287 no_result: function() {
288 if (this.view.options.action.help) {
290 $('<div class="oe_view_nocontent">')
291 .append($('<div>').html(this.view.options.action.help || " "))
295 do_reload: function() {
296 var view_manager = this.view.getParent(),
297 action_manager = view_manager.getParent();
299 action_manager.do_action(view_manager.action);
302 instance.web.form.DashBoardLegacy = instance.web.form.DashBoard.extend({
303 renderElement: function() {
304 if (this.node.tag == 'hpaned') {
305 this.node.attrs.layout = '2-1';
306 } else if (this.node.tag == 'vpaned') {
307 this.node.attrs.layout = '1';
309 this.node.tag = 'board';
310 _.each(this.node.children, function(child) {
311 if (child.tag.indexOf('child') == 0) {
312 child.tag = 'column';
313 var actions = [], first_child = child.children[0];
314 if (first_child && first_child.tag == 'vpaned') {
315 _.each(first_child.children, function(subchild) {
316 actions.push.apply(actions, subchild.children);
318 child.children = actions;
326 instance.web.form.tags.add('hpaned', 'instance.web.form.DashBoardLegacy');
327 instance.web.form.tags.add('vpaned', 'instance.web.form.DashBoardLegacy');
328 instance.web.form.tags.add('board', 'instance.web.form.DashBoard');
331 instance.web.search.FavoriteMenu.include({
332 prepare_dropdown_menu: function (filters) {
334 this._super(filters);
335 this.$('.favorites-menu').append(QWeb.render('SearchView.addtodashboard'));
336 var $add_to_dashboard = this.$('.add-to-dashboard');
337 this.$add_dashboard_btn = $add_to_dashboard.eq(2).find('button');
338 this.$add_dashboard_input = $add_to_dashboard.eq(1).find('input');
339 this.$add_dashboard_link = $add_to_dashboard.first().find('a');
340 var title = this.searchview.getParent().title;
341 this.$add_dashboard_input.val(title);
342 this.$add_dashboard_link.click(function () {
343 self.toggle_dashboard_menu();
345 this.$add_dashboard_btn.click(this.proxy('add_dashboard'));
347 toggle_dashboard_menu: function (is_open) {
348 this.$add_dashboard_link
349 .toggleClass('closed-menu', !is_open)
350 .toggleClass('open-menu', is_open);
351 this.$add_dashboard_btn.toggle(is_open);
352 this.$add_dashboard_input.toggle(is_open);
353 if (this.$add_dashboard_link.hasClass('open-menu')) {
354 this.$add_dashboard_input.focus();
357 close_menus: function () {
358 this.toggle_dashboard_menu(false);
361 add_dashboard: function () {
363 view_manager = this.findAncestor(function (a) {
364 return a instanceof instance.web.ViewManager
366 if (!view_manager.action) {
367 this.do_warn(_t("Can't find dashboard action"));
370 var searchview = view_manager.searchview,
371 data = searchview.build_search_data(),
372 context = new instance.web.CompoundContext(searchview.dataset.get_context() || []),
373 domain = new instance.web.CompoundDomain(searchview.dataset.get_domain() || []);
374 _.each(data.contexts, context.add, context);
375 _.each(data.domains, domain.add, domain);
378 group_by: instance.web.pyeval.eval('groupbys', data.groupbys || [])
380 var c = instance.web.pyeval.eval('context', context);
382 if (c.hasOwnProperty(k) && /^search_default_/.test(k)) {
386 this.toggle_dashboard_menu(false);
387 c.dashboard_merge_domains_contexts = false;
388 var d = instance.web.pyeval.eval('domain', domain),
389 board = new instance.web.Model('board.board'),
390 name = self.$add_dashboard_input.val();
392 board.call('list', [board.context()])
393 .then(function (board_list) {
394 return self.rpc('/board/add_to_dashboard', {
395 menu_id: board_list[0].id,
396 action_id: view_manager.action.id,
399 view_mode: view_manager.active_view.type,
402 }).then(function (r) {
404 self.do_notify(_.str.sprintf(_t("'%s' added to dashboard"), name), '');
406 self.do_warn(_t("Could not add filter to dashboard"));