[IMP] factorize view/load part2 addons
[odoo/odoo.git] / addons / web_kanban / static / src / js / kanban.js
1 openerp.web_kanban = function (openerp) {
2
3 QWeb.add_template('/web_kanban/static/src/xml/web_kanban.xml');
4 openerp.web.views.add('kanban', 'openerp.web_kanban.KanbanView');
5 openerp.web_kanban.KanbanView = openerp.web.View.extend({
6     init: function (parent, element_id, dataset, view_id, options) {
7         this._super(parent, element_id);
8         this.set_default_options(options);
9         this.dataset = dataset;
10         this.model = dataset.model;
11         this.domain = dataset.domain;
12         this.context = dataset.context;
13         this.view_id = view_id;
14         this.fields_view = {};
15         this.group_by = [];
16         this.source_index = {};
17         this.all_display_data = false;
18         this.groups = [];
19         this.qweb = new QWeb2.Engine();
20     },
21     start: function() {
22         return this.rpc("/web/view/load", {"model": this.model, "view_id": this.view_id, "view_type": "kanban"}, this.on_loaded);
23     },
24     on_loaded: function(data) {
25         var self = this;
26         this.fields_view = data;
27         this.add_qweb_template();
28         if (this.qweb.has_template('kanban-box')) {
29             self.dataset.read_slice(_.keys(self.fields_view.fields), {
30                     context: self.dataset.get_context(),
31                     domain: self.dataset.get_domain()
32                 }, function (records) {
33                     self.all_display_data = [{'records': records, 'value': false, 'header': false, 'ids': self.dataset.ids}];
34                     self.on_show_data(self.all_display_data);
35                 }
36             );
37         }
38     },
39     add_qweb_template: function() {
40         for (var i=0, ii=this.fields_view.arch.children.length; i < ii; i++) {
41             var child = this.fields_view.arch.children[i];
42             if (child.tag === "templates") {
43                 this.transform_qweb_template(child);
44                 this.qweb.add_template(openerp.web.json_node_to_xml(child));
45                 break;
46             }
47         }
48     },
49     do_get_kanban_color: function(variable) {
50         var number_of_color_schemes = 2,
51             index = 0;
52         switch (typeof(variable)) {
53             case 'string':
54                 for (var i=0, ii=variable.length; i<ii; i++) {
55                     index += variable.charCodeAt(i);
56                 }
57                 break;
58             case 'number':
59                 index = Math.round(variable);
60                 break;
61             default:
62                 return '';
63         }
64         return 'oe_kanban_color_' + ((index % number_of_color_schemes) + 1);
65     },
66     transform_qweb_template: function(node) {
67         switch (node.tag) {
68             case 'field':
69                 node.tag = 't';
70                 node.attrs['t-esc'] = node.attrs['name'] + '.value';
71                 break
72             case 'button':
73             case 'a':
74                 var type = node.attrs.type || '';
75                 if (_.indexOf('action,object,edit,delete,'.split(','), type) !== -1) {
76                     _.each(node.attrs, function(v, k) {
77                         node.attrs['data-' + k] = v;
78                         delete(node.attrs[k]);
79                     });
80                     if (node.attrs['data-states']) {
81                         var states = _.map(node.attrs['data-states'].split(','), function(state) {
82                             return "state.value == '" + _.trim(state) + "'";
83                         });
84                         node.attrs['t-if'] = states.join(' or ');
85                     }
86                     if (node.attrs['data-string']) {
87                         node.attrs.title = node.attrs['data-string'];
88                     }
89                     if (node.attrs['data-icon']) {
90                         node.children = [{
91                             tag: 'img',
92                             attrs: {
93                                 src: '/web/static/src/img/icons/' + node.attrs['data-icon'] + '.png',
94                                 width: '16',
95                                 height: '16'
96                             }
97                         }];
98                     }
99                     if (node.tag == 'a') {
100                         node.attrs.href = '#';
101                     } else {
102                         node.attrs.type = 'button';
103                     }
104                     node.attrs['class'] = (node.attrs['class'] || '') + ' oe_kanban_action oe_kanban_action_' + node.tag;
105                 }
106                 break;
107         }
108         if (node.children) {
109             for (var i = 0, ii = node.children.length; i < ii; i++) {
110                 this.transform_qweb_template(node.children[i]);
111             }
112         }
113     },
114     on_show_data: function(data) {
115         var self = this;
116         this.$element.html(QWeb.render("KanbanView", {"data": data}));
117         this.on_reload_kanban();
118         var drag_handel = false;
119         if (this.$element.find(".oe_kanban_draghandle").length > 0) {
120             drag_handel = ".oe_kanban_draghandle";
121         }
122         this.$element.find(".oe_column").sortable({
123             connectWith: ".oe_column",
124             handle : drag_handel,
125             start: function(event, ui) {
126                 self.source_index['index'] = ui.item.index();
127                 self.source_index['column'] = ui.item.parent().attr('id');
128             },
129             stop: self.on_receive_record,
130         });
131         this.$element.find(".oe_column").disableSelection()
132         this.$element.find('button.oe_kanban_button_new').click(this.do_add_record);
133     },
134     on_button_click: function (button_attrs, record_id) {
135         var self = this;
136         if (this.groups.length) {
137             _.each(this.groups, function (group) {
138                 group.list([],
139                     function (groups) {},
140                     function (dataset) {
141                         dataset.read_slice([], {}, function(records) {
142                             var index = parseInt(_.indexOf(dataset.ids, record_id));
143                             if(index >= 0) {
144                                 self.on_confirm_click(dataset, button_attrs, index, record_id);
145                             }
146                         });
147                     }
148                 );
149             });
150         } else {
151             var index = parseInt(_.indexOf(self.dataset.ids, record_id));
152             if (index >= 0) {
153                 _.extend(self.dataset, {domain: self.domain, context: self.context});
154                 self.on_confirm_click(self.dataset, button_attrs, index, record_id);
155             }
156         }
157     },
158     on_confirm_click: function (dataset, button_attrs, index, record_id) {
159         if (button_attrs.type == 'edit') {
160             this.do_edit_record(dataset, index);
161         } else {
162             this.on_execute_button_click(dataset, button_attrs, record_id);
163         }
164     },
165     do_add_record: function () {
166         this.do_edit_record(this.dataset, null);
167     },
168     do_edit_record: function (dataset, index) {
169         var self = this;
170         _.extend(this.dataset, {
171             domain: dataset.domain,
172             context: dataset.get_context()
173         }).read_slice([], {}, function () {
174             self.dataset.index = index;
175             self.do_switch_view('form');
176         });
177     },
178     do_delete: function (id) {
179         var self = this;
180         return $.when(this.dataset.unlink([id])).then(function () {
181             self.drop_records(id);
182         });
183     },
184     drop_records: function (id) {
185         var self = this;
186         _.each(self.all_display_data, function(data, index) {
187             _.each(data.records, function(record, index_row) {
188                 if (parseInt(record.id) == id) {
189                     self.all_display_data[index]['records'].splice(index_row, 1);
190                     self.all_display_data[index]['ids'].splice(index_row, 1);
191                     return false;
192                 }
193             });
194         });
195         self.$element.find("#main_" + id).remove();
196     },
197     on_execute_button_click: function (dataset, button_attrs, record_id) {
198         var self = this;
199         this.execute_action(
200             button_attrs, dataset,
201             record_id, function () {
202                 var count = 1;
203                 _.each(self.all_display_data, function(data, index) {
204                     self.dataset.read_ids( data.ids, [], function(records){
205                         self.all_display_data[index].records = records;
206                         if(self.all_display_data.length == count) {
207                             self.do_actual_search();
208                         }
209                         count++;
210                     });
211                 });
212             }
213         );
214     },
215     on_receive_record: function (event, ui) {
216         var self = this;
217         var from = ui.item.index();
218         var search_action = false;
219         var to = ui.item.prev().index() || 0;
220         if (!ui.item.attr("id")) {
221             return false;
222         }
223         // TODO fme: check what was this sequence
224         if (self.fields_view.fields.sequence && (self.source_index.index >= 0 && self.source_index.index != from) ||
225                 (self.source_index.column && self.source_index.column != ui.item.parent().attr('id'))) {
226             var child_record = ui.item.parent().children();
227             var data, sequence = 1, index = to;
228             child_record.splice(0, to);
229             var flag = false;
230             if (to >= 0 && child_record) {
231                 var record_id = parseInt($(child_record).attr("id").split("_")[1]);
232                 if (record_id) {
233                     _.each(self.all_display_data, function(data, index) {
234                         _.each(data.records, function(record, index_row) {
235                             if(record_id == record.id && record.sequence) {
236                                 sequence = record.sequence;
237                                 flag = true;
238                                 return false;
239                             }
240                         });
241                         if(flag) {return false;}
242                     });
243                 }
244             }
245             _.each(child_record, function (child) {
246                 var child_id = parseInt($(child).attr("id").split("_")[1]);
247                 if (child_id) {
248                     flag = false;
249                     _.each(self.all_display_data, function(data, index) {
250                         _.each(data.records, function(record, index_row) {
251                             if(parseInt(record.id) == child_id) {
252                                 self.all_display_data[index]['records'][index_row]['sequence'] = sequence;
253                                 flag = true;
254                                 return false;
255                             }
256                         });
257                         if (flag) {return false;}
258                     });
259                     self.dataset.write(child_id, {sequence: sequence});
260                     sequence++;
261                     search_action = true;
262                 }
263             });
264         }
265         if (self.group_by.length > 0 && self.source_index.column && self.source_index.column != ui.item.parent().attr('id')) {
266             var value = ui.item.closest("td").attr("id");
267             if (value) {
268                 var data_val = {};
269                 var wirte_id = parseInt(ui.item.attr("id").split("_")[1]);
270                 value = value.split("_")[1];
271                 if (value == 'false') {
272                     value = false;
273                 }
274                 var update_record = false;
275                 _.each(self.all_display_data, function(data, index) {
276                     _.each(data.records, function(record, index_row) {
277                         if(parseInt(record.id) == wirte_id) {
278                             self.all_display_data[index]['records'][index_row][self.group_by[0]] = value;
279                             update_record = self.all_display_data[index]['records'].splice(index_row,1)
280                             return false;
281                         }
282                     });
283                     if (update_record) {return false;}
284                 });
285                 _.each(self.all_display_data, function(data, index) {
286                     if (data.value == value || (data.value == 'false' && value == false)) {
287                         self.all_display_data[index]['records'].push(update_record[0]);
288                     }
289                 });
290                 data_val[self.group_by[0]] = value;
291                 self.dataset.write(wirte_id, data_val);
292                 search_action = true;
293             }
294         }
295         if (search_action) {
296             self.on_reload_kanban();
297         }
298         this.source_index = {};
299     },
300     on_reload_kanban: function (){
301         var self = this;
302         _.each(self.all_display_data, function(data, index) {
303             if (data.records.length > 0){
304                 _.each(data.records, function(record) {
305                     self.$element.find("#main_" + record.id).children().remove();
306                     self.$element.find("#main_" + record.id).append(self.qweb.render('kanban-box', self.do_transform_record(record)));
307                 });
308             } else {
309                 self.$element.find("#column_" + data.value).remove();
310                 self.all_display_data.splice(index, 1);
311             }
312         });
313         this.$element.find('.oe_kanban_action').click(function() {
314             var record_id = $(this).closest(".oe_kanban_record").attr("id");
315             if (record_id) {
316                 record_id = parseInt(record_id.split("_")[1])
317                 if (record_id) {
318                     if ($(this).data("type") == "delete") {
319                         self.do_delete(record_id);
320                     } else {
321                         var button_attrs = $(this).data()
322                         self.on_button_click(button_attrs, record_id);
323                     }
324                 }
325             }
326         });
327         this.$element.find('.oe_kanban_record').click(function() {
328             $(this).find('.oe_kanban_box_show_onclick').removeClass('oe_kanban_box_show_onclick');
329         });
330     },
331     do_transform_record: function(record) {
332         var self = this,
333             new_record = {};
334         _.each(record, function(value, name) {
335             var r = _.clone(self.fields_view.fields[name]);
336             r.raw_value = value;
337             r.value = openerp.web.format_value(value, r);
338             new_record[name] = r;
339         });
340         new_record.__kanban_color = this.do_get_kanban_color;
341         return new_record;
342     },
343     do_search: function (domains, contexts, group_by) {
344         var self = this;
345         this.rpc('/web/session/eval_domain_and_context', {
346             domains: domains,
347             contexts: contexts,
348             group_by_seq: group_by
349         }, function (results) {
350             self.domain = results.domain;
351             self.context = results.context;
352             self.group_by = results.group_by;
353             self.do_actual_search();
354         });
355     },
356     do_actual_search : function () {
357         var self = this;
358         self.datagroup = new openerp.web.DataGroup(self, self.model, self.domain, self.context, self.group_by || []);
359         self.dataset.context = self.context;
360         self.dataset.domain = self.domain;
361         self.datagroup.list([],
362             function (groups) {
363                 self.groups = groups;
364                 self.do_render_group(groups);
365             },
366             function (dataset) {
367                 self.domain = dataset.domain;
368                 self.context = dataset.context;
369                 self.groups = [];
370                 self.dataset.read_slice([], {}, function(records) {
371                     self.all_display_data = [{'records': records, 'value':false, 'header' : false, 'ids': self.dataset.ids}];
372                     self.$element.find(".oe_kanban_view").remove();
373                     self.on_show_data(self.all_display_data);
374                 });
375             }
376         );
377     },
378     do_render_group : function (datagroups) {
379         this.all_display_data = [];
380         var self = this;
381         _.each(datagroups, function (group) {
382             self.dataset.context = group.context;
383             self.dataset.domain = group.domain;
384             var group_name = group.value;
385             var group_value = group.value;
386             if (!group.value) {
387                 group_name = "Undefined";
388                 group_value = 'false';
389             } else if (group.value instanceof Array) {
390                 group_name = group.value[1];
391                 group_value = group.value[0];
392             }
393             self.dataset.read_slice([], {}, function(records) {
394                 self.all_display_data.push({"value" : group_value, "records": records, 'header':group_name, 'ids': self.dataset.ids});
395                 if (datagroups.length == self.all_display_data.length) {
396                     self.$element.find(".oe_kanban_view").remove();
397                     self.on_show_data(self.all_display_data);
398                 }
399             });
400         });
401     },
402     do_show: function () {
403         this.$element.show();
404     },
405     do_hide: function () {
406         this.$element.hide();
407     }
408 });
409 };
410
411 // vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: