[IMP] Connection: new method to bind to a server. Must be called before login
[odoo/odoo.git] / addons / web / static / src / js / data_export.js
1 openerp.web.data_export = function(openerp) {
2 var QWeb = openerp.web.qweb;
3 openerp.web.DataExport = openerp.web.Dialog.extend({
4     template: 'ExportTreeView',
5     dialog_title: 'Export Data',
6     init: function(parent, dataset) {
7         this._super(parent);
8         this.records = {};
9         this.dataset = dataset;
10         this.exports = new openerp.web.DataSetSearch(
11             this, 'ir.exports', this.dataset.get_context());
12     },
13     start: function() {
14         var self = this;
15         this._super.apply(this, arguments);
16         this.open({
17             modal: true,
18             width: '55%',
19             height: 'auto',
20             position: 'top',
21             buttons : {
22                 "Close" : function() {
23                     self.close();
24                   },
25                 "Export To File" : function() {
26                     self.on_click_export_data();
27                   }
28                },
29             close: function(event, ui){ self.close();}
30         });
31         self.$element.removeClass('ui-dialog-content ui-widget-content');
32         self.$element.find('#add_field').click(function() {
33             if ($('#field-tree-structure tr.ui-selected')) {
34                 var fld = self.$element.find('#field-tree-structure tr.ui-selected').find('a');
35                 for (var i = 0; i < fld.length; i++) {
36                     var id = $(fld[i]).attr('id').split('-')[1];
37                     var string = $(fld[i]).attr('string');
38                     self.add_field(id, string);
39                 }
40                 self.$element.find('#field-tree-structure tr').removeClass('ui-selected');
41             }
42         });
43         self.$element.find('#remove_field').click(function() {
44             self.$element.find('#fields_list option:selected').remove();
45         });
46         self.$element.find('#remove_all_field').click(function() {
47             self.$element.find('#fields_list').empty();
48         });
49         this.$element.find('#export_new_list').click(this.on_show_save_list);
50
51         var got_fields = new $.Deferred();
52         this.$element.find('#import_compat').change(function() {
53             self.$element.find('#fields_list').empty();
54             self.$element.find('#field-tree-structure').remove();
55             var import_comp = self.$element.find("#import_compat").val();
56             self.rpc("/web/export/get_fields", {
57                 model: self.dataset.model,
58                 import_compat: Boolean(import_comp)
59             }, function (records) {
60                 got_fields.resolve();
61                 self.on_show_data(records);
62             });
63         }).change();
64
65         return $.when(
66             got_fields,
67             this.rpc('/web/export/formats', {}, this.do_setup_export_formats),
68             this.show_exports_list());
69     },
70     do_setup_export_formats: function (formats) {
71         var $fmts = this.$element.find('#export_format');
72         _(formats).each(function (format) {
73             $fmts.append(new Option(format[1], format[0]));
74         });
75     },
76     show_exports_list: function() {
77         var self = this;
78         if (self.$element.find('#saved_export_list').is(':hidden')) {
79             self.$element.find('#ExistsExportList').show();
80             return;
81         }
82         return this.exports.read_slice(['name'], {
83             domain: [['resource', '=', this.dataset.model]]
84         }, function (export_list) {
85             if (!export_list.length) {
86                 return;
87             }
88             self.$element.find('#ExistsExportList').append(QWeb.render('Exists.ExportList', {'existing_exports': export_list}));
89             self.$element.find('#saved_export_list').change(function() {
90                 self.$element.find('#fields_list option').remove();
91                 var export_id = self.$element.find('#saved_export_list option:selected').val();
92                 if (export_id) {
93                     self.rpc('/web/export/namelist', {'model': self.dataset.model, export_id: parseInt(export_id)}, self.do_load_export_field);
94                 }
95             });
96             self.$element.find('#delete_export_list').click(function() {
97                 var select_exp = self.$element.find('#saved_export_list option:selected');
98                 if (select_exp.val()) {
99                     self.exports.unlink([parseInt(select_exp.val(), 10)]);
100                     select_exp.remove();
101                     if (self.$element.find('#saved_export_list option').length <= 1) {
102                         self.$element.find('#ExistsExportList').hide();
103                     }
104                 }
105             });
106         });
107     },
108     do_load_export_field: function(field_list) {
109         var export_node = this.$element.find("#fields_list");
110         _(field_list).each(function (field) {
111             export_node.append(new Option(field.label, field.name));
112         });
113     },
114     on_show_save_list: function() {
115         var self = this;
116         var current_node = self.$element.find("#savenewlist");
117         if (!(current_node.find("label")).length) {
118             current_node.append(QWeb.render('ExportNewList'));
119             current_node.find("#add_export_list").click(function() {
120                 var value = current_node.find("#savelist_name").val();
121                 if (value) {
122                     self.do_save_export_list(value);
123                 } else {
124                     alert("Pleae Enter Save Field List Name");
125                 }
126             });
127         } else {
128             if (current_node.is(':hidden')) {
129                 current_node.show();
130                 current_node.find("#savelist_name").val("");
131             } else {
132                current_node.hide();
133             }
134         }
135     },
136     do_save_export_list: function(value) {
137         var self = this;
138         var fields = self.get_fields();
139         if (!fields.length) {
140             return;
141         }
142         this.exports.create({
143             name: value,
144             resource: this.dataset.model,
145             export_fields: _(fields).map(function (field) {
146                 return [0, 0, {name: field}];
147             })
148         }, function (export_list_id) {
149             if (!export_list_id.result) {
150                 return;
151             }
152             self.$element.find("#saved_export_list").append(
153                     new Option(value, export_list_id.result));
154             if (self.$element.find("#saved_export_list").is(":hidden")) {
155                 self.show_exports_list();
156             }
157         });
158         this.on_show_save_list();
159         this.$element.find("#fields_list option").remove();
160     },
161     on_click: function(id, record) {
162         var self = this;
163         if (!record['children']) {
164             return;
165         }
166         var model = record['params']['model'],
167             prefix = record['params']['prefix'],
168             name = record['params']['name'],
169             exclude_fields = [];
170         if (record['relation_field']) {
171             exclude_fields.push(record['relation_field']);
172         }
173
174         if (!record.loaded) {
175             var import_comp = self.$element.find("#import_compat").val();
176             self.rpc("/web/export/get_fields", {
177                 model: model,
178                 prefix: prefix,
179                 parent_name: name,
180                 import_compat: Boolean(import_comp),
181                 parent_field_type : record['field_type'],
182                 exclude: exclude_fields
183             }, function(results) {
184                 record.loaded = true;
185                 self.on_show_data(results, record.id);
186             });
187         } else {
188             self.showcontent(record.id);
189         }
190     },
191     on_show_data: function(result, after) {
192         var self = this;
193         var imp_cmpt = Boolean(self.$element.find("#import_compat").val());
194
195         if (after) {
196             var current_tr = self.$element.find("tr[id='treerow-" + after + "']");
197             current_tr.addClass('open');
198             current_tr.find('img').attr('src','/web/static/src/img/collapse.gif');
199             current_tr.after(QWeb.render('ExportTreeView-Secondary.children', {'fields': result}));
200         } else {
201             self.$element.find('#left_field_panel').append(QWeb.render('ExportTreeView-Secondary', {'fields': result}));
202         }
203         _.each(result, function(record) {
204             self.records[record.id] = record.value;
205             if (record.required) {
206                 var required_fld = self.$element.find("tr[id='treerow-" + record.id + "']").find('#tree-column');
207                 required_fld.addClass("oe_export_requiredfield");
208             }
209             self.$element.find("img[id='parentimg-" + record.id +"']").click(function() {
210                 self.on_click(this.id, record);
211             });
212
213             self.$element.find("tr[id='treerow-" + record.id + "']").click(function(e) {
214                 if (e.shiftKey) {
215                     var frst_click, scnd_click = '';
216                     if (self.row_index == 0) {
217                         self.row_index = this.rowIndex;
218                         frst_click = self.$element.find("tr[id^='treerow-']")[self.row_index-1];
219                         $(frst_click).addClass("ui-selected");
220                     } else {
221                         if (this.rowIndex >=self.row_index) {
222                             for (var i = (self.row_index-1); i < this.rowIndex; i++) {
223                                 scnd_click = self.$element.find("tr[id^='treerow-']")[i];
224                                 if (!$(scnd_click).find('#tree-column').hasClass("oe_export_readonlyfield")) {
225                                     $(scnd_click).addClass("ui-selected");
226                                 }
227                             }
228                         } else {
229                             for (var i = (self.row_index-1); i >= (this.rowIndex-1); i--) {
230                                 scnd_click = self.$element.find("tr[id^='treerow-']")[i];
231                                 if (!$(scnd_click).find('#tree-column').hasClass("oe_export_readonlyfield")) {
232                                     $(scnd_click).addClass("ui-selected");
233                                 }
234                             }
235                         }
236                     }
237                 }
238                 self.row_index = this.rowIndex;
239
240                 self.$element.find("tr[id='treerow-" + record.id + "']").keyup(function() {
241                     self.row_index = 0;
242                 });
243                 var o2m_selection = self.$element.find("tr[id='treerow-" + record.id + "']").find('#tree-column');
244                 if ($(o2m_selection).hasClass("oe_export_readonlyfield")) {
245                     return false;
246                 }
247                 if (e.ctrlKey) {
248                     if ($(this).hasClass('ui-selected')) {
249                         $(this).removeClass('ui-selected').find('a').blur();
250                     } else {
251                         $(this).addClass('ui-selected').find('a').focus();
252                     }
253                 } else if (!e.shiftKey) {
254                     self.$element.find("tr.ui-selected")
255                             .removeClass("ui-selected").find('a').blur();
256                     $(this).addClass("ui-selected").find('a').focus();
257                 }
258                 return false;
259             });
260
261             self.$element.find("tr[id='treerow-" + record.id + "']").keydown(function(e) {
262                 var keyCode = e.keyCode || e.which;
263                 var arrow = {left: 37, up: 38, right: 39, down: 40 };
264                 switch (keyCode) {
265                     case arrow.left:
266                         if ($(this).hasClass('open')) {
267                             self.on_click(this.id, record);
268                         }
269                         break;
270                     case arrow.right:
271                         if (!$(this).hasClass('open')) {
272                             self.on_click(this.id, record);
273                         }
274                         break;
275                     case arrow.up:
276                         var elem = this;
277                         $(elem).removeClass("ui-selected");
278                         while (!$(elem).prev().is(":visible")) {
279                             elem = $(elem).prev();
280                         }
281                         if (!$(elem).prev().find('#tree-column').hasClass("oe_export_readonlyfield")) {
282                             $(elem).prev().addClass("ui-selected");
283                         }
284                         $(elem).prev().find('a').focus();
285                         break;
286                     case arrow.down:
287                         var elem = this;
288                         $(elem).removeClass("ui-selected");
289                         while(!$(elem).next().is(":visible")) {
290                             elem = $(elem).next();
291                         }
292                         if (!$(elem).next().find('#tree-column').hasClass("oe_export_readonlyfield")) {
293                             $(elem).next().addClass("ui-selected");
294                         }
295                         $(elem).next().find('a').focus();
296                         break;
297                 }
298             });
299             self.$element.find("tr[id='treerow-" + record.id + "']").dblclick(function() {
300                 var $o2m_selection = self.$element.find("tr[id^='treerow-" + record.id + "']").find('#tree-column');
301                 if (!$o2m_selection.hasClass("oe_export_readonlyfield")) {
302                    self.add_field(record.id, $(this).find("a").attr("string"));
303                 }
304             });
305         });
306         self.$element.find('#fields_list').mouseover(function(event) {
307             if (event.relatedTarget) {
308                 if (event.relatedTarget.attributes['id'] && event.relatedTarget.attributes['string']) {
309                     var field_id = event.relatedTarget.attributes["id"]["value"];
310                     if (field_id && field_id.split("-")[0] === 'export') {
311                         if (!self.$element.find("tr[id='treerow-" + field_id.split("-")[1] + "']").find('#tree-column').hasClass("oe_export_readonlyfield")) {
312                             self.add_field(field_id.split("-")[1], event.relatedTarget.attributes["string"]["value"]);
313                         }
314                     }
315                 }
316             }
317         });
318     },
319     showcontent: function(id) {
320         // show & hide the contents
321         var $this = this.$element.find("tr[id='treerow-" + id + "']");
322         var is_open = $this.hasClass('open');
323         $this.toggleClass('open');
324
325         var first_child = $this.find('img');
326         if (is_open) {
327             first_child.attr('src', '/web/static/src/img/expand.gif');
328         } else {
329             first_child.attr('src', '/web/static/src/img/collapse.gif');
330         }
331         var child_field = this.$element.find("tr[id^='treerow-" + id +"/']");
332         var child_len = (id.split("/")).length + 1;
333         for (var i = 0; i < child_field.length; i++) {
334             var $child = $(child_field[i]);
335             if (is_open) {
336                 $child.hide();
337             } else if (child_len == (child_field[i].id.split("/")).length) {
338                 if ($child.hasClass('open')) {
339                     $child.removeClass('open');
340                     $child.find('img').attr('src', '/web/static/src/img/expand.gif');
341                 }
342                 $child.show();
343             }
344         }
345     },
346     add_field: function(field_id, string) {
347         var field_list = this.$element.find('#fields_list');
348         if (this.$element.find("#fields_list option[value='" + field_id + "']")
349                 && !this.$element.find("#fields_list option[value='" + field_id + "']").length) {
350             field_list.append(new Option(string, field_id));
351         }
352     },
353     get_fields: function() {
354         var export_field = [];
355         this.$element.find("#fields_list option").each(function() {
356             export_field.push($(this).val());
357         });
358         if (!export_field.length) {
359             alert('Please select fields to save export list...');
360         }
361         return export_field;
362     },
363     on_click_export_data: function() {
364         $.blockUI(this.$element);
365         var exported_fields = [], self = this;
366         this.$element.find("#fields_list option").each(function() {
367             var fieldname = self.records[$(this).val()];
368             exported_fields.push({name: fieldname, label: $(this).text()});
369         });
370         if (_.isEmpty(exported_fields)) {
371             alert('Please select fields to export...');
372             return;
373         }
374
375         exported_fields.unshift({name: 'id', label: 'External ID'});
376         var export_format = this.$element.find("#export_format").val();
377         this.session.get_file({
378             url: '/web/export/' + export_format,
379             data: {data: JSON.stringify({
380                 model: this.dataset.model,
381                 fields: exported_fields,
382                 ids: this.dataset.ids,
383                 domain: this.dataset.domain,
384                 import_compat: Boolean(
385                         this.$element.find("#import_compat").val())
386             })},
387             complete: $.unblockUI
388         });
389     },
390     close: function() {
391         $(this.$dialog).remove();
392         this._super();
393     }
394 });
395
396 };