From 7a9ca47e214d662360e8e5f3a00bb21a10e375d2 Mon Sep 17 00:00:00 2001 From: Mohammed Shekha Date: Tue, 18 Jun 2013 17:31:54 +0530 Subject: [FIX]Fixed the issue of save selected fields list in export. bzr revid: msh@openerp.com-20130618120154-o0cj17snpn00mh38 --- addons/web/static/src/js/data_export.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/data_export.js b/addons/web/static/src/js/data_export.js index fb5e391effd..31a750e787e 100644 --- a/addons/web/static/src/js/data_export.js +++ b/addons/web/static/src/js/data_export.js @@ -101,6 +101,7 @@ instance.web.DataExport = instance.web.Dialog.extend({ if (select_exp.val()) { self.exports.unlink([parseInt(select_exp.val(), 10)]); select_exp.remove(); + self.$el.find("#fields_list option").remove(); if (self.$el.find('#saved_export_list option').length <= 1) { self.$el.find('#ExistsExportList').hide(); } @@ -148,18 +149,17 @@ instance.web.DataExport = instance.web.Dialog.extend({ export_fields: _(fields).map(function (field) { return [0, 0, {name: field}]; }) - }, function (export_list_id) { - if (!export_list_id.result) { + }).then(function (export_list_id) { + if (!export_list_id) { return; } - self.$el.find("#saved_export_list").append( - new Option(value, export_list_id.result)); - if (self.$el.find("#saved_export_list").is(":hidden")) { + if (!self.$el.find("#saved_export_list").length || self.$el.find("#saved_export_list").is(":hidden")) { self.show_exports_list(); } + self.$el.find("#saved_export_list").append( + new Option(value, export_list_id)); }); this.on_show_save_list(); - this.$el.find("#fields_list option").remove(); }, on_click: function(id, record) { var self = this; -- cgit v1.2.3 From 2e3ec5e2e92b76703eecb76d31c085157aba5b98 Mon Sep 17 00:00:00 2001 From: Mohammed Shekha Date: Wed, 3 Jul 2013 18:42:23 +0530 Subject: [FIX]Fixed the issue of last element of grouped row removed, due to which grouped total information also got lost. bzr revid: msh@openerp.com-20130703131223-bwu6hl8v5y5sjt5w --- addons/web/static/src/js/view_list.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 74c2fc47aee..a9f110eac28 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -1280,7 +1280,8 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we } }, close: function () { - this.$row.children().last().empty(); + this.$row.children().last().find('button').remove(); + this.$row.children().last().find('span').remove(); this.records.reset(); }, /** -- cgit v1.2.3 From e578e2af784cb3af11ceae7d07cc07c7036a85e9 Mon Sep 17 00:00:00 2001 From: "Mohammed Shekha (OpenERP)" Date: Thu, 17 Oct 2013 18:32:17 +0530 Subject: [FIX]Fix the issue of page navigation when all records of current page are deleted, currently it does not go to previous page instead displays blank list, expected behavior: it should navigated to previous page when all records of the current page deleted. bzr revid: msh@openerp.com-20131017130217-dtpukpq27fdmsvd9 --- addons/web/static/src/js/view_list.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 74c2fc47aee..dd8b62ae619 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -593,7 +593,13 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi _(ids).each(function (id) { self.records.remove(self.records.get(id)); }); - self.configure_pager(self.dataset); + if (self.records.length == 0 && self.page > 0) { + //Trigger previous manually to navigate to previous page, + //If all records are deleted on current page. + self.$pager.find('ul li:first a').trigger('click'); + } else { + self.configure_pager(self.dataset); + } self.compute_aggregates(); }); }, -- cgit v1.2.3 From fa9f3676879d1978b2e8d025533777d6b5bb41b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 18 Oct 2013 15:22:59 +0200 Subject: [IMP] form_view: statusbar improvements It now uses the bar_fold field instead of the fold field to hide the stage. It now uses bar_color to personnalize the stage. Added css for oe_bar_1 (still WIP, just for testing purpose) bzr revid: tde@openerp.com-20131018132259-2kip8723ibr296ri --- addons/web/static/src/js/view_form.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index bcea1bf5bbe..6f19455fc0b 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -5522,16 +5522,24 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ if (this.field.type == "many2one") { return self.get_distant_fields().then(function(fields) { return new instance.web.DataSetSearch(self, self.field.relation, self.build_context(), self.get("evaluated_selection_domain")) - .read_slice(fields.fold ? ['fold'] : ['id'], {}).then(function (records) { + .read_slice(_.union(_.keys(self.distant_fields), ['id']), {}).then(function (records) { + console.log(records); + var ids = _.pluck(records, 'id'); - var ids = _.map(records, function (val) {return val.id;}); + // var ids = _.map(records, function (val) {return val.id;}); return self.dataset.name_get(ids).then(function (records_name) { _.each(records, function (record) { var name = _.find(records_name, function (val) {return val[0] == record.id;})[1]; - if (record.fold && record.id != self.get('value')) { - selection_folded.push([record.id, name]); + var widget_item = { + 'id': record.id, + 'name': name, + 'bar_color': record.bar_color || 0, + 'bar_fold': record.bar_fold || false, + } + if (record.bar_fold && record.id != self.get('value')) { + selection_folded.push(widget_item); } else { - selection_unfolded.push([record.id, name]); + selection_unfolded.push(widget_item); } }); }); @@ -5563,7 +5571,7 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ if (this.distant_fields) { return $.when(this.distant_fields); } - return new instance.web.Model(self.field.relation).call("fields_get", [["fold"]]).then(function(fields) { + return new instance.web.Model(self.field.relation).call("fields_get", [["bar_fold", "bar_color"]]).then(function(fields) { self.distant_fields = fields; return fields; }); -- cgit v1.2.3 From a28c14a8ccfd09dc07e2bcc606daac629097e9dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 21 Oct 2013 12:47:08 +0200 Subject: [REV] StatusField: reverted changes about bar widget color and thing slike that. bzr revid: tde@openerp.com-20131021104708-vrax9zhpjwyjq6ns --- addons/web/static/src/js/view_form.js | 1 - 1 file changed, 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 6f19455fc0b..0ca5f39e387 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -5523,7 +5523,6 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ return self.get_distant_fields().then(function(fields) { return new instance.web.DataSetSearch(self, self.field.relation, self.build_context(), self.get("evaluated_selection_domain")) .read_slice(_.union(_.keys(self.distant_fields), ['id']), {}).then(function (records) { - console.log(records); var ids = _.pluck(records, 'id'); // var ids = _.map(records, function (val) {return val.id;}); -- cgit v1.2.3 From 2d78686db75c390cec4db191ddea45fce0cef629 Mon Sep 17 00:00:00 2001 From: "ajay javiya (OpenERP)" Date: Mon, 21 Oct 2013 19:20:04 +0530 Subject: [REF]: Refector many2many_tags bzr revid: aja@tinyerp.com-20131021135004-rmxft7jrvbixhekx --- addons/web/static/src/js/view_form.js | 52 +++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 17 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 7a0890bdcfa..8bff844a540 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -4216,6 +4216,7 @@ var lazy_build_o2m_kanban_view = function() { instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(instance.web.form.CompletionFieldMixin, instance.web.form.ReinitializeFieldMixin, { template: "FieldMany2ManyTags", + tag_template: "FieldMany2ManyTag", init: function() { this._super.apply(this, arguments); instance.web.form.CompletionFieldMixin.init.call(this); @@ -4223,13 +4224,9 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in this._display_orderer = new instance.web.DropMisordered(); this._drop_shown = false; }, - initialize_content: function() { - if (this.get("effective_readonly")) - return; + initialize_texttext: function(){ var self = this; - var ignore_blur = false; - self.$text = this.$("textarea"); - self.$text.textext({ + return { plugins : 'tags arrow autocomplete', autocomplete: { render: function(suggestion) { @@ -4280,7 +4277,15 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in }, }, }, - }).bind('getSuggestions', function(e, data) { + } + }, + initialize_content: function() { + if (this.get("effective_readonly")) + return; + var self = this; + var ignore_blur = false; + self.$text = this.$("textarea"); + self.$text.textext(self.initialize_texttext()).bind('getSuggestions', function(e, data) { var _this = this; var str = !!data ? data.query || '' : ''; self.get_search_result(str).done(function(result) { @@ -4328,6 +4333,24 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in get_search_blacklist: function() { return this.get("value"); }, + map_tag: function(data){ + return _.map(data, function(el) {return {name: el[1], id:el[0]};}) + }, + get_render_data: function(ids){ + var self = this; + var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context()); + return dataset.name_get(ids); + }, + render_tag: function(data) { + var self = this; + if (! self.get("effective_readonly")) { + self.tags.containerElement().children().remove(); + self.$('textarea').css("padding-left", "3px"); + self.tags.addTags(self.map_tag(data)); + } else { + self.$el.html(QWeb.render(self.tag_template, {elements: data})); + } + }, render_value: function() { var self = this; var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context()); @@ -4340,17 +4363,12 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in indexed[el[0]] = el; }); data = _.map(values, function(el) { return indexed[el]; }); - if (! self.get("effective_readonly")) { - self.tags.containerElement().children().remove(); - self.$('textarea').css("padding-left", "3px"); - self.tags.addTags(_.map(data, function(el) {return {name: el[1], id:el[0]};})); - } else { - self.$el.html(QWeb.render("FieldMany2ManyTag", {elements: data})); - } - }; + self.render_tag(data); + } if (! values || values.length > 0) { - this._display_orderer.add(dataset.name_get(values)).done(handle_names); - } else { + this._display_orderer.add(self.get_render_data(values)).done(handle_names); + } + else{ handle_names([]); } }, -- cgit v1.2.3 From 833c1f207213bd742f229ddb0954096c1559494d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 23 Oct 2013 14:08:04 +0200 Subject: [IMP] view_form: fieldstatus: deprecated folded on widget bzr revid: tde@openerp.com-20131023120804-vx7etkzewkgx9sk0 --- addons/web/static/src/js/view_form.js | 47 +++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 22 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 707d1b8dcd8..bbaaa2c04f7 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -5520,30 +5520,30 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ var calculation = _.bind(function() { if (this.field.type == "many2one") { - return self.get_distant_fields().then(function(fields) { - return new instance.web.DataSetSearch(self, self.field.relation, self.build_context(), self.get("evaluated_selection_domain")) - .read_slice(_.union(_.keys(self.distant_fields), ['id']), {}).then(function (records) { - var ids = _.pluck(records, 'id'); - - // var ids = _.map(records, function (val) {return val.id;}); - return self.dataset.name_get(ids).then(function (records_name) { - _.each(records, function (record) { - var name = _.find(records_name, function (val) {return val[0] == record.id;})[1]; - var widget_item = { - 'id': record.id, - 'name': name, - 'bar_color': record.bar_color || 0, - 'bar_fold': record.bar_fold || false, - } - if (record.bar_fold && record.id != self.get('value')) { - selection_folded.push(widget_item); - } else { - selection_unfolded.push(widget_item); - } - }); + /* :deprecated: fold feature will probably be removed */ + // return self.get_distant_fields().then(function(fields) { + self.distant_fields = {}; + return new instance.web.DataSetSearch(self, self.field.relation, self.build_context(), self.get("evaluated_selection_domain")) + .read_slice(_.union(_.keys(self.distant_fields), ['id']), {}).then(function (records) { + var ids = _.pluck(records, 'id'); + return self.dataset.name_get(ids).then(function (records_name) { + _.each(records, function (record) { + var name = _.find(records_name, function (val) {return val[0] == record.id;})[1]; + var widget_item = { + 'id': record.id, + 'name': name, + /* :deprecated: should probably be removed */ + 'bar_color': record.bar_color || 0, + 'bar_fold': record.bar_fold || false, + } + if (record.bar_fold && record.id != self.get('value')) { + selection_folded.push(widget_item); + } else { + selection_unfolded.push(widget_item); + } }); }); - }); + }); } else { // For field type selection filter values according to // statusbar_visible attribute of the field. For example: @@ -5565,6 +5565,9 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ } }); }, + /* + * :deprecated: this feature will probably be removed with OpenERP v8 + */ get_distant_fields: function() { var self = this; if (this.distant_fields) { -- cgit v1.2.3 From 4c460dfa4e65b68a59a52d0797d081331614ea54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 4 Nov 2013 12:59:09 +0100 Subject: [REV] Reverted most changes, to lessen the number of changed in a stable branch. bzr revid: tde@openerp.com-20131104115909-exhujer0lqqr4xk5 --- addons/web/static/src/js/view_form.js | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index bbaaa2c04f7..c4e7733a70e 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -5527,22 +5527,15 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ .read_slice(_.union(_.keys(self.distant_fields), ['id']), {}).then(function (records) { var ids = _.pluck(records, 'id'); return self.dataset.name_get(ids).then(function (records_name) { - _.each(records, function (record) { - var name = _.find(records_name, function (val) {return val[0] == record.id;})[1]; - var widget_item = { - 'id': record.id, - 'name': name, - /* :deprecated: should probably be removed */ - 'bar_color': record.bar_color || 0, - 'bar_fold': record.bar_fold || false, - } - if (record.bar_fold && record.id != self.get('value')) { - selection_folded.push(widget_item); - } else { - selection_unfolded.push(widget_item); - } + _.each(records, function (record) { + var name = _.find(records_name, function (val) {return val[0] == record.id;})[1]; + if (record.fold && record.id != self.get('value')) { + selection_folded.push([record.id, name]); + } else { + selection_unfolded.push([record.id, name]); + } + }); }); - }); }); } else { // For field type selection filter values according to -- cgit v1.2.3 From 0ff21fc5e8fc687b22a4010e83460732b73fcc0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Mon, 4 Nov 2013 13:03:24 +0100 Subject: [REV] view_form: statusbar widget: indentation issue + reverted some more changes bzr revid: tde@openerp.com-20131104120324-2h2j6huhgwc134c9 --- addons/web/static/src/js/view_form.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index c4e7733a70e..8c5188620d8 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -5527,15 +5527,15 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ .read_slice(_.union(_.keys(self.distant_fields), ['id']), {}).then(function (records) { var ids = _.pluck(records, 'id'); return self.dataset.name_get(ids).then(function (records_name) { - _.each(records, function (record) { - var name = _.find(records_name, function (val) {return val[0] == record.id;})[1]; - if (record.fold && record.id != self.get('value')) { - selection_folded.push([record.id, name]); - } else { - selection_unfolded.push([record.id, name]); - } - }); + _.each(records, function (record) { + var name = _.find(records_name, function (val) {return val[0] == record.id;})[1]; + if (record.fold && record.id != self.get('value')) { + selection_folded.push([record.id, name]); + } else { + selection_unfolded.push([record.id, name]); + } }); + }); }); } else { // For field type selection filter values according to @@ -5566,7 +5566,7 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ if (this.distant_fields) { return $.when(this.distant_fields); } - return new instance.web.Model(self.field.relation).call("fields_get", [["bar_fold", "bar_color"]]).then(function(fields) { + return new instance.web.Model(self.field.relation).call("fields_get", [["fold"]]).then(function(fields) { self.distant_fields = fields; return fields; }); -- cgit v1.2.3 From db7573384800fdea71bad45cd980237eeff5cccb Mon Sep 17 00:00:00 2001 From: niv-openerp Date: Thu, 7 Nov 2013 12:20:17 +0100 Subject: [FIX] rare race condition in BufferedDataset lp bug: https://launchpad.net/bugs/1248531 fixed bzr revid: nicolas.vanhoren@openerp.com-20131107112017-7omd01ocvnbzx9m6 --- addons/web/static/src/js/data.js | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index f4e1b5a9c57..fe572dffbcb 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -780,6 +780,7 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({ this._super.apply(this, arguments); this.reset_ids([]); this.last_default_get = {}; + this.running_reads = []; }, default_get: function(fields, options) { var self = this; @@ -846,6 +847,9 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({ this.to_write = []; this.cache = []; this.delete_all = false; + _.each(_.clone(this.running_reads), function(el) { + el.reject(); + }); }, read_ids: function (ids, fields, options) { var self = this; @@ -861,7 +865,6 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({ to_get.push(id); } }); - var completion = $.Deferred(); var return_records = function() { var records = _.map(ids, function(id) { return _.extend({}, _.detect(self.cache, function(c) {return c.id === id;}).values, {"id": id}); @@ -896,10 +899,20 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({ }, 0); }); } - completion.resolve(records); + return $.when(records); }; if(to_get.length > 0) { - var rpc_promise = this._super(to_get, fields, options).done(function(records) { + var def = $.Deferred(); + self.running_reads.push(def); + def.always(function() { + self.running_reads = _.without(self.running_reads, def); + }); + this._super(to_get, fields, options).then(function() { + def.resolve.apply(def, arguments); + }, function() { + def.reject.apply(def, arguments); + }); + return def.then(function(records) { _.each(records, function(record, index) { var id = to_get[index]; var cached = _.detect(self.cache, function(x) {return x.id === id;}); @@ -910,13 +923,11 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({ cached.values = _.defaults(_.clone(cached.values), record); } }); - return_records(); + return return_records(); }); - $.when(rpc_promise).fail(function() {completion.reject();}); } else { - return_records(); + return return_records(); } - return completion.promise(); }, /** * Invalidates caching of a record in the dataset to ensure the next read -- cgit v1.2.3 From a48e79335509f96f9dd386b8ca08f6f7de494f52 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 7 Nov 2013 15:32:12 +0100 Subject: [FIX] web: correct cookie parsing. avoid reading wrong cookie by matching the whole cookie name bzr revid: chs@openerp.com-20131107143212-50hrpvkaw3gxxlop --- addons/web/static/src/js/openerpframework.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/openerpframework.js b/addons/web/static/src/js/openerpframework.js index 1d688505a06..9f3a6352511 100644 --- a/addons/web/static/src/js/openerpframework.js +++ b/addons/web/static/src/js/openerpframework.js @@ -1209,15 +1209,14 @@ openerp.TranslationDataBase = openerp.Class.extend(/** @lends instance.Translati openerp._t = new openerp.TranslationDataBase().build_translation_function(); openerp.get_cookie = function(c_name) { - if (document.cookie.length > 0) { - var c_start = document.cookie.indexOf(c_name + "="); - if (c_start != -1) { - c_start = c_start + c_name.length + 1; - var c_end = document.cookie.indexOf(";", c_start); - if (c_end == -1) { - c_end = document.cookie.length; - } - return unescape(document.cookie.substring(c_start, c_end)); + var cookies = document.cookie ? document.cookie.split('; ') : []; + for (var i = 0, l = cookies.length; i < l; i++) { + var parts = cookies[i].split('='); + var name = parts.shift(); + var cookie = parts.join('='); + + if (c_name && c_name === name) { + return cookie; } } return ""; -- cgit v1.2.3 From 5311db325cf62f38db906c3f769e035837e68ded Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 8 Nov 2013 17:06:27 +0100 Subject: [FIX] web: filter context before executing actions triggered by buttons in views bzr revid: chs@openerp.com-20131108160627-osiigir6tsr2k783 --- addons/web/static/src/js/views.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index ecdbaf8b465..6a181fc4dc7 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -1354,7 +1354,17 @@ instance.web.View = instance.web.Widget.extend({ return self.getParent().on_action_executed.apply(null, arguments); } }; - var context = new instance.web.CompoundContext(dataset.get_context(), action_data.context || {}); + var context = dataset.get_context(); + if (action_data.model !== dataset.model) { + // filter out context keys that are specific to the action model. + // Wrong default_ and search_default values will no give the expected views + // Wrong group_by values will simply fail and forbid rendering of the destination view + context = _.object(_.reject(_.pairs(context.eval()), function(pair) { + return pair[0].match('^(?:(?:default_|search_default_).+|group_by|group_by_no_leaf)$') !== null; + })); + } + + context = new instance.web.CompoundContext(context, action_data.context || {}); var handler = function (action) { if (action && action.constructor == Object) { var ncontext = new instance.web.CompoundContext(context); -- cgit v1.2.3 From be7084b988c23df09c4eef40aa54e01eb73ed0a4 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 8 Nov 2013 17:07:47 +0100 Subject: [FIX] web: do not declare variables inside if() scope bzr revid: chs@openerp.com-20131108160747-1jrpihb66y6vtov5 --- addons/web/static/src/js/views.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 6a181fc4dc7..1ee89238e7d 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -1178,11 +1178,12 @@ instance.web.Sidebar = instance.web.Widget.extend({ var self = this; self.getParent().sidebar_eval_context().done(function (sidebar_eval_context) { var ids = self.getParent().get_selected_ids(); + var domain; if (self.getParent().get_active_domain) { - var domain = self.getParent().get_active_domain(); + domain = self.getParent().get_active_domain(); } else { - var domain = $.Deferred().resolve(undefined); + domain = $.Deferred().resolve(undefined); } if (ids.length === 0) { instance.web.dialog($("
").text(_t("You must choose at least one record.")), { title: _t("Warning"), modal: true }); -- cgit v1.2.3 From 8214e291a9eafeb39b61dd923dce00b3cce1dccc Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 31 Oct 2013 08:39:20 -0500 Subject: [FIX] web: correct date and datetime parsing. When creating a new Date object at a specific date, this date is treated as a UTC datetime then normalized to the browser timezone. This can lead to a change of Year/Month/Day depending of the chosen date. Using a date of a leap year date for date parsing and forcing UTC date for datetime parsing correct the month-switch errors in all timezones bzr revid: chs@openerp.com-20131031133920-yl5z4oz939smwvz8 --- addons/web/static/src/js/openerpframework.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/openerpframework.js b/addons/web/static/src/js/openerpframework.js index 9f3a6352511..1704856886b 100644 --- a/addons/web/static/src/js/openerpframework.js +++ b/addons/web/static/src/js/openerpframework.js @@ -1264,7 +1264,10 @@ openerp.str_to_datetime = function(str) { if ( !res ) { throw new Error("'" + str + "' is not a valid datetime"); } - var tmp = new Date(0); + var tmp = new Date(2000,0,1); + tmp.setUTCMonth(1970); + tmp.setUTCMonth(0); + tmp.setUTCDate(1); tmp.setUTCFullYear(parseFloat(res[1])); tmp.setUTCMonth(parseFloat(res[2]) - 1); tmp.setUTCDate(parseFloat(res[3])); @@ -1296,7 +1299,7 @@ openerp.str_to_date = function(str) { if ( !res ) { throw new Error("'" + str + "' is not a valid date"); } - var tmp = new Date(0); + var tmp = new Date(2000,0,1); tmp.setFullYear(parseFloat(res[1])); tmp.setMonth(parseFloat(res[2]) - 1); tmp.setDate(parseFloat(res[3])); -- cgit v1.2.3 From 4476cd670112e2aff612e945d626ce03f28f3a6e Mon Sep 17 00:00:00 2001 From: niv-openerp Date: Wed, 13 Nov 2013 16:21:07 +0100 Subject: [FIX] problem when clicking too fast on pagers in the form view lp bug: https://launchpad.net/bugs/1238569 fixed bzr revid: nicolas.vanhoren@openerp.com-20131113152107-5zwsbntil4wihoh4 --- addons/web/static/src/js/view_form.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 2cb318dcb17..94fc38faa23 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -399,9 +399,11 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM this.dataset.index = this.dataset.ids.length - 1; break; } - this.reload(); + var def = this.reload(); this.trigger('pager_action_executed'); + return def; } + return $.when(); }, init_pager: function() { var self = this; @@ -416,8 +418,15 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM this.$el.find('.oe_form_pager').replaceWith(this.$pager); } this.$pager.on('click','a[data-pager-action]',function() { - var action = $(this).data('pager-action'); - self.execute_pager_action(action); + var $el = $(this); + if ($el.attr("disabled")) + return; + var action = $el.data('pager-action'); + var def = $.when(self.execute_pager_action(action)); + $el.attr("disabled"); + def.always(function() { + $el.removeAttr("disabled"); + }); }); this.do_update_pager(); }, -- cgit v1.2.3 From 30e6eadf421565341f22baf2ff9d6130436df551 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 13 Nov 2013 11:22:04 +0100 Subject: [FIX] fixes a problem in pyeval catching all exceptions silently bzr revid: ged@openerp.com-20131113102204-m0gox7odwgkmon4o --- addons/web/static/src/js/pyeval.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/pyeval.js b/addons/web/static/src/js/pyeval.js index 0b0e9725af9..b10c175c683 100644 --- a/addons/web/static/src/js/pyeval.js +++ b/addons/web/static/src/js/pyeval.js @@ -845,16 +845,18 @@ }; instance.web.pyeval.eval_domains_and_contexts = function (source) { return new $.Deferred(function (d) {setTimeout(function () { + var result; try { var contexts = ([instance.session.user_context] || []).concat(source.contexts); // see Session.eval_context in Python - d.resolve({ + result = { context: instance.web.pyeval.eval('contexts', contexts), domain: instance.web.pyeval.eval('domains', source.domains), group_by: instance.web.pyeval.eval('groupbys', source.group_by_seq || []) - }); + }; + } catch (e) { - d.resolve({ error: { + result = { error: { code: 400, message: instance.web._t("Evaluation Error"), data: { @@ -863,8 +865,9 @@ instance.web._t("Local evaluation failure\n%s\n\n%s"), e.message, JSON.stringify(source)) } - }}); + }}; } + d.resolve(result); }, 0); }); }; })(); -- cgit v1.2.3 From a3e4cdef515469a5988fe97b03bc89c58e9655f5 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 13 Nov 2013 16:19:11 +0100 Subject: [ADD] hacky abort() proxy for json requests bzr revid: xmo@openerp.com-20131113151911-l4f7vlzkcht38nuc --- addons/web/static/src/js/openerpframework.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/openerpframework.js b/addons/web/static/src/js/openerpframework.js index e986a2f4112..a2e4c06d67d 100644 --- a/addons/web/static/src/js/openerpframework.js +++ b/addons/web/static/src/js/openerpframework.js @@ -809,7 +809,8 @@ var genericJsonRpc = function(fct_name, params, fct) { params: params, id: Math.floor(Math.random() * 1000 * 1000 * 1000) }; - return fct(data).pipe(function(result) { + var xhr = fct(data); + var result = xhr.pipe(function(result) { if (result.error !== undefined) { console.error("Server application error", result.error); return $.Deferred().reject("server", result.error); @@ -821,6 +822,9 @@ var genericJsonRpc = function(fct_name, params, fct) { var def = $.Deferred(); return def.reject.apply(def, ["communication"].concat(_.toArray(arguments))); }); + // FIXME: jsonp? + result.abort = function () { xhr.abort && xhr.abort(); }; + return result; }; openerp.jsonRpc = function(url, fct_name, params, settings) { -- cgit v1.2.3 From e9c633cb7e8053d63a31d1d1f375dc10347a0389 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 13 Nov 2013 19:40:00 +0100 Subject: [IMP] web: call call_kw with full route to help debugging bzr revid: chs@openerp.com-20131113184000-3k3dnwl5ftllq2rv --- addons/web/static/src/js/openerpframework.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/openerpframework.js b/addons/web/static/src/js/openerpframework.js index 1704856886b..99d11b58ca9 100644 --- a/addons/web/static/src/js/openerpframework.js +++ b/addons/web/static/src/js/openerpframework.js @@ -1128,7 +1128,8 @@ openerp.Model = openerp.Class.extend({ kwargs = args; args = []; } - return this.session().rpc('/web/dataset/call_kw', { + var call_kw = _.str.sprintf('/web/dataset/call_kw/%s/%s', this.name, method); + return this.session().rpc(call_kw, { model: this.name, method: method, args: args, -- cgit v1.2.3 From b61997e71671c7640ca3fe271804de46550c8502 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 14 Nov 2013 10:46:24 +0100 Subject: [FIX] web: correct url matching in tests bzr revid: chs@openerp.com-20131114094624-588lvc9vunwa99d8 --- addons/web/static/src/js/testing.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/testing.js b/addons/web/static/src/js/testing.js index a7768f0ca24..f607b278437 100644 --- a/addons/web/static/src/js/testing.js +++ b/addons/web/static/src/js/testing.js @@ -58,8 +58,7 @@ openerp.testing = {}; } var fn, params; var needle = rparams.model + ':' + rparams.method; - if (url.url === '/web/dataset/call_kw' - && needle in this.responses) { + if (url.url.substr(0, 20) === '/web/dataset/call_kw' && needle in this.responses) { fn = this.responses[needle]; params = [ rparams.args || [], -- cgit v1.2.3 From bb9c83714ad9b194eca10901a0c3c5d4c2559c82 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 18 Nov 2013 11:21:12 +0100 Subject: [FIX] Avoid rpc errors on actions.act.url@target='self' bzr revid: fme@openerp.com-20131118102112-znm2mza36md6896n --- addons/web/static/src/js/views.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index ecdbaf8b465..2d05b5b41dc 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -510,7 +510,11 @@ instance.web.ActionManager = instance.web.Widget.extend({ }); }, ir_actions_act_url: function (action) { - window.open(action.url, action.target === 'self' ? '_self' : '_blank'); + if (action.target === 'self') { + instance.web.redirect(action.url); + } else { + window.open(action.url, '_blank'); + } return $.when(); }, }); -- cgit v1.2.3 From 9ded116baf006f9eb7a6674bf298ad9f185de6c5 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 18 Nov 2013 12:22:11 +0100 Subject: [ADD] return_label & return_url in action_manager#load_state for breadcrumb bzr revid: fme@openerp.com-20131118112211-q15p0d7cc8wpku5n --- addons/web/static/src/js/views.js | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 2d05b5b41dc..5e9cfa07399 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -147,6 +147,19 @@ instance.web.ActionManager = instance.web.Widget.extend({ this.inner_action = last_widget.action; } }, + add_breadcrumb_url: function (url, label) { + // Add a pseudo breadcrumb that will redirect to an url + this.push_breadcrumb({ + show: function(index) { + instance.web.redirect(url); + }, + hide: function() {}, + destroy: function() {}, + get_title: function() { + return label; + } + }); + }, get_title: function() { var titles = []; for (var i = 0; i < this.breadcrumbs.length; i += 1) { @@ -217,6 +230,12 @@ instance.web.ActionManager = instance.web.Widget.extend({ do_load_state: function(state, warm) { var self = this, action_loaded; + if (!warm && 'return_label' in state) { + var return_url = state.return_url || document.referrer; + if (return_url) { + this.add_breadcrumb_url(return_url, state.return_label); + } + } if (state.action) { if (_.isString(state.action) && instance.web.client_actions.contains(state.action)) { var action_client = { @@ -225,7 +244,9 @@ instance.web.ActionManager = instance.web.Widget.extend({ params: state, _push_me: state._push_me, }; - this.null_action(); + if (warm) { + this.null_action(); + } action_loaded = this.do_action(action_client); } else { var run_action = (!this.inner_widget || !this.inner_widget.action) || this.inner_widget.action.id !== state.action; @@ -245,7 +266,9 @@ instance.web.ActionManager = instance.web.Widget.extend({ add_context.active_ids = [state.active_id]; } add_context.params = state; - this.null_action(); + if (warm) { + this.null_action(); + } action_loaded = this.do_action(state.action, { additional_context: add_context }); $.when(action_loaded || null).done(function() { instance.webclient.menu.has_been_loaded.done(function() { @@ -258,7 +281,9 @@ instance.web.ActionManager = instance.web.Widget.extend({ } } else if (state.model && state.id) { // TODO handle context & domain ? - this.null_action(); + if (warm) { + this.null_action(); + } var action = { res_model: state.model, res_id: state.id, @@ -268,7 +293,9 @@ instance.web.ActionManager = instance.web.Widget.extend({ action_loaded = this.do_action(action); } else if (state.sa) { // load session action - this.null_action(); + if (warm) { + this.null_action(); + } action_loaded = this.rpc('/web/session/get_session_action', {key: state.sa}).then(function(action) { if (action) { return self.do_action(action); -- cgit v1.2.3 From 7c9be80f9558229effb5abf0d428f62d97f7cc96 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 18 Nov 2013 19:06:42 +0100 Subject: [FIX] jquery browser detection fix bzr revid: al@openerp.com-20131118180642-xa39ja4o8zt8zd5o --- addons/web/static/src/js/core.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 8c69f86c47e..3e2b93a8ead 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -586,6 +586,10 @@ instance.web.TranslationDataBase.include({ }); /** Custom jQuery plugins */ +if(navigator.appVersion.indexOf("MSIE") !== -1) { + $.browser = $.browser || {}; + $.browser.msie = 1; +} $.fn.getAttributes = function() { var o = {}; if (this.length) { -- cgit v1.2.3 From 8721307dae148af6d4381f849de495aafd4bf77b Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 20 Nov 2013 19:53:37 +0100 Subject: [IMP] web: avoid double reload() when clicking on a button on a editable form view. bzr revid: chs@openerp.com-20131120185337-w8857fmwosa36r4d --- addons/web/static/src/js/view_form.js | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index bd04b4c75d0..080cd6f70aa 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -720,12 +720,13 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM var self = this; return this.save().done(function(result) { self.trigger("save", result); - self.to_view_mode(); - }).then(function(result) { - var parent = self.ViewManager.ActionManager.getParent(); - if(parent){ - parent.menu.do_reload_needaction(); - } + self.reload().then(function() { + self.to_view_mode(); + var parent = self.ViewManager.ActionManager.getParent(); + if(parent){ + parent.menu.do_reload_needaction(); + } + }); }); }, on_button_cancel: function(event) { @@ -889,17 +890,12 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM * @param {Object} r result of the write function. */ record_saved: function(r) { - var self = this; + this.trigger('record_saved', r); if (!r) { // should not happen in the server, but may happen for internal purpose - this.trigger('record_saved', r); return $.Deferred().reject(); - } else { - return $.when(this.reload()).then(function () { - self.trigger('record_saved', r); - return r; - }); } + return r; }, /** * Updates the form' dataset to contain the new record: -- cgit v1.2.3 From e5558726465419e4c6dce68601c47325941e15a9 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 22 Nov 2013 14:10:37 +0100 Subject: [FIX] web: view list: ensure that the mutex of synchronized method `reload_content` is always released. bzr revid: chs@openerp.com-20131122131037-sqxs1fdh4al32eh2 --- addons/web/static/src/js/view_list.js | 41 ++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index b9c789cb6a9..868a218f70e 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -501,23 +501,38 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi self.$el.find('.oe_list_record_selector').prop('checked', false); this.records.reset(); var reloaded = $.Deferred(); - this.$el.find('.oe_list_content').append( - this.groups.render(function () { - if (self.dataset.index == null) { - if (self.records.length) { + + setTimeout(function() { + var $group; + try { + $group = self.groups.render(function () { + // NOTE using == instead of === is wanted. + if (self.dataset.index == null) { // jshint ignore:line + if (self.records.length) { + self.dataset.index = 0; + } + } else if (self.dataset.index >= self.records.length) { self.dataset.index = 0; } - } else if (self.dataset.index >= self.records.length) { - self.dataset.index = 0; + + self.compute_aggregates(); + }); + } finally { + // ensure that the deferred is always rejected/resolved to quit the + // synchronized block properly. + if (_.isUndefined($group)) { + reloaded.reject(); + } else { + reloaded.resolve(); + self.$el.find('.oe_list_content').append($group); + self.do_push_state({ + page: self.page, + limit: self._limit + }); } + } - self.compute_aggregates(); - reloaded.resolve(); - })); - this.do_push_state({ - page: this.page, - limit: this._limit - }); + }, 0); return reloaded.promise(); }), reload: function () { -- cgit v1.2.3 From 5c080a1634fd408905996756c1fbac10220e3881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 22 Nov 2013 14:59:59 +0100 Subject: [IMP] webclient: Introducing the FullscreenWidget, enabling fullscreen behavior and fixed zoomlevels on mobile devices bzr revid: fva@openerp.com-20131122135959-ezv9cmgwp2zfkt00 --- addons/web/static/src/js/chrome.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index f019972fd14..56559e9edb9 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1223,6 +1223,26 @@ instance.web.UserMenu = instance.web.Widget.extend({ }, }); +instance.web.FullscreenWidget = instance.web.Widget.extend({ + /** + * Widgets extending the FullscreenWidget will be displayed fullscreen, + * and will have a fixed 1:1 zoom level on mobile devices. + */ + start: function(){ + if(!$('#oe-fullscreenwidget-viewport').length){ + $('head').append(''); + } + instance.webclient.set_content_full_screen(true); + return this._super(); + }, + destroy: function(){ + instance.webclient.set_content_full_screen(false); + $('#oe-fullscreenwidget-viewport').remove(); + return this._super(); + }, + +}); + instance.web.Client = instance.web.Widget.extend({ init: function(parent, origin) { instance.client = instance.webclient = this; -- cgit v1.2.3 From 0a76694628e0f10e4ae2a809f3a2b08d899ffa06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 22 Nov 2013 15:00:48 +0100 Subject: [IMP] webclient: Introducing SimpleIndexedDB, a key value wrapper around IndexedDB bzr revid: fva@openerp.com-20131122140048-goaplzrx26jvcmmu --- addons/web/static/src/js/data.js | 151 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index 04f657d91f7..76164657d84 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -1090,6 +1090,157 @@ instance.web.DropMisordered = instance.web.Class.extend({ } }); +instance.web.SimpleIndexedDB = instance.web.Class.extend({ + /** + * A simple wrapper around IndexedDB that provides an asynchronous + * localStorage-like Key-Value api that persists between browser + * restarts. + * + * It will not work if the browser doesn't support a recent version + * of IndexedDB, and it may fail if the user refuses db access. + * + * All instances of SimpleIndexedDB will by default refer to the same + * IndexedDB database, if you want to pick another one, use the 'name' + * option on instanciation. + */ + init: function(opts){ + var self = this; + var opts = opts || {}; + + this.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; + this.db = undefined; + this._ready = new $.Deferred(); + + if(this.indexedDB && this.indexedDB.open){ + var request = this.indexedDB.open( opts.name || "SimpleIndexedDB" ,1); + + request.onerror = function(event){ + self.db = null; + self._ready.reject(event.target.error); + }; + + request.onsuccess = function(event){ + self.db = request.result; + self._ready.resolve(); + }; + + request.onupgradeneeded = function(event){ + self.db = event.target.result; + + var objectStore = self.db.createObjectStore("keyvals", { keyPath:"key" }); + self._ready.resolve(); + }; + }else{ + this.db = null; + this._ready.reject({type:'UnknownError', message:'IndexedDB is not supported by your Browser'}); + } + }, + + /** + * returns true if the browser supports the necessary IndexedDB API + * (but doesn't tell if the db can be created, check ready() for that) + */ + isSupportedByBrowser: function(){ + return this.indexedDB && this.indexedDB.open; + }, + + /** + * returns a deferred that resolves when the db has been successfully + * initialized. done/failed callbacks are optional. + */ + ready: function(done,failed){ + this._ready.then(done,failed); + return this._ready.promise(); + }, + + /** + * fetches the value associated to 'key' in the db. if the key doesn't + * exists, it returns undefined. The returned value is provided as a + * deferred, or as the first parameter of the optional 'done' callback. + */ + getItem: function(key,done,failed){ + var self = this; + var def = new $.Deferred(); + def.then(done,failed); + + this._ready.then(function(){ + var request = self.db.transaction(["keyvals"],"readwrite") + .objectStore("keyvals") + .get(key); + + request.onsuccess = function(){ + def.resolve(request.result ? request.result.value : undefined); + }; + + request.onerror = function(event){ + def.reject(event.target.error); + }; + },function(){ + def.reject({type:'UnknownError', message:'Could not initialize the IndexedDB database'}); + }); + + return def.promise(); + }, + + /** + * Associates a value to 'key' in the db, overwriting previous value if + * necessary. Contrary to localStorage, the value is not limited to strings and + * can be any javascript object, even with cyclic references ! + * + * Be sure to check for failure as the user may refuse to have data localy stored. + */ + setItem: function(key,value,done,failed){ + var self = this; + var def = new $.Deferred(); + def.then(done,failed); + + this._ready.then(function(){ + var request = self.db.transaction(["keyvals"],"readwrite") + .objectStore("keyvals") + .put( {key:key, value:value} ); + + request.onsuccess = function(){ + def.resolve(); + }; + + request.onerror = function(event){ + def.reject(event.target.error); + }; + },function(){ + def.reject({type:'UnknownError', message:'Could not initialize the IndexedDB database'}); + }); + + return def.promise(); + }, + + /** + * Removes the value associated with 'key' from the db. + */ + removeItem: function(key,done,failed){ + var self = this; + var def = new $.Deferred(); + def.then(done,failed); + + this._ready.then(function(){ + var request = self.db.transaction(["keyvals"],"readwrite") + .objectStore("keyvals") + .delete(key); + + request.onsuccess = function(){ + def.resolve(); + }; + + request.onerror = function(event){ + def.reject(event.target.error); + }; + },function(){ + def.reject({type:'UnknownError', message:'Could not initialize the IndexedDB database'}); + }); + + return def.promise(); + }, +}); + })(); // vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: -- cgit v1.2.3 From 1be71fdae6d01169b50dff6f3eb7657a98436dce Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 22 Nov 2013 18:03:16 +0100 Subject: [REVERT] revert previous commit which: 1. is wrong 2. break runbot bzr revid: chs@openerp.com-20131122170316-lbuxddprrgz1are3 --- addons/web/static/src/js/view_list.js | 41 +++++++++++------------------------ 1 file changed, 13 insertions(+), 28 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 868a218f70e..b9c789cb6a9 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -501,38 +501,23 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi self.$el.find('.oe_list_record_selector').prop('checked', false); this.records.reset(); var reloaded = $.Deferred(); - - setTimeout(function() { - var $group; - try { - $group = self.groups.render(function () { - // NOTE using == instead of === is wanted. - if (self.dataset.index == null) { // jshint ignore:line - if (self.records.length) { - self.dataset.index = 0; - } - } else if (self.dataset.index >= self.records.length) { + this.$el.find('.oe_list_content').append( + this.groups.render(function () { + if (self.dataset.index == null) { + if (self.records.length) { self.dataset.index = 0; } - - self.compute_aggregates(); - }); - } finally { - // ensure that the deferred is always rejected/resolved to quit the - // synchronized block properly. - if (_.isUndefined($group)) { - reloaded.reject(); - } else { - reloaded.resolve(); - self.$el.find('.oe_list_content').append($group); - self.do_push_state({ - page: self.page, - limit: self._limit - }); + } else if (self.dataset.index >= self.records.length) { + self.dataset.index = 0; } - } - }, 0); + self.compute_aggregates(); + reloaded.resolve(); + })); + this.do_push_state({ + page: this.page, + limit: this._limit + }); return reloaded.promise(); }), reload: function () { -- cgit v1.2.3 From 727b188eac4eb61134aca3666e861af3923776e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 27 Nov 2013 10:50:37 +0100 Subject: [IMP] form_view: statusbar widget: folded back as an option. The widget option 'fold_field' allows to tell the widget to use this field on the model used for stages to compute the folded selection. If not set, no stage is folded. bzr revid: tde@openerp.com-20131127095037-me1cvl272ex1e6r9 --- addons/web/static/src/js/view_form.js | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 8b985695860..683cdebbbf4 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -5552,23 +5552,23 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ var self = this; var selection_unfolded = []; var selection_folded = []; + var fold_field = this.options.fold_field; var calculation = _.bind(function() { if (this.field.type == "many2one") { - /* :deprecated: fold feature will probably be removed */ - // return self.get_distant_fields().then(function(fields) { - self.distant_fields = {}; - return new instance.web.DataSetSearch(self, self.field.relation, self.build_context(), self.get("evaluated_selection_domain")) - .read_slice(_.union(_.keys(self.distant_fields), ['id']), {}).then(function (records) { - var ids = _.pluck(records, 'id'); - return self.dataset.name_get(ids).then(function (records_name) { - _.each(records, function (record) { - var name = _.find(records_name, function (val) {return val[0] == record.id;})[1]; - if (record.fold && record.id != self.get('value')) { - selection_folded.push([record.id, name]); - } else { - selection_unfolded.push([record.id, name]); - } + return self.get_distant_fields().then(function (fields) { + return new instance.web.DataSetSearch(self, self.field.relation, self.build_context(), self.get("evaluated_selection_domain")) + .read_slice(_.union(_.keys(self.distant_fields), ['id']), {}).then(function (records) { + var ids = _.pluck(records, 'id'); + return self.dataset.name_get(ids).then(function (records_name) { + _.each(records, function (record) { + var name = _.find(records_name, function (val) {return val[0] == record.id;})[1]; + if (fold_field && record[fold_field] && record.id != self.get('value')) { + selection_folded.push([record.id, name]); + } else { + selection_unfolded.push([record.id, name]); + } + }); }); }); }); @@ -5598,10 +5598,13 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ */ get_distant_fields: function() { var self = this; + if (! this.options.fold_field) { + this.distant_fields = {} + } if (this.distant_fields) { return $.when(this.distant_fields); } - return new instance.web.Model(self.field.relation).call("fields_get", [["fold"]]).then(function(fields) { + return new instance.web.Model(self.field.relation).call("fields_get", [[this.options.fold_field]]).then(function(fields) { self.distant_fields = fields; return fields; }); -- cgit v1.2.3 From e468eeb9b30af8ff54c006657d79f5cff32919c4 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 28 Nov 2013 14:46:07 +0100 Subject: [FIX] web_form: FieldMany2ManyBinaryMultiFiles error when rendering twice (with an onchange for e.g.) bzr revid: chm@openerp.com-20131128134607-2fisdnoq0qgpvibx --- addons/web/static/src/js/view_form.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 94fc38faa23..57ac87c8d09 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -5379,25 +5379,26 @@ instance.web.form.FieldMany2ManyBinaryMultiFiles = instance.web.form.AbstractFie read_name_values : function () { var self = this; // don't reset know values - var _value = _.filter(this.get('value'), function (id) { return typeof self.data[id] == 'undefined'; } ); + var ids = this.get('value'); + var _value = _.filter(ids, function (id) { return typeof self.data[id] == 'undefined'; } ); // send request for get_name if (_value.length) { - return this.ds_file.call('read', [_value, ['id', 'name', 'datas_fname']]).done(function (datas) { + return this.ds_file.call('read', [_value, ['id', 'name', 'datas_fname']]).then(function (datas) { _.each(datas, function (data) { data.no_unlink = true; data.url = self.session.url('/web/binary/saveas', {model: 'ir.attachment', field: 'datas', filename_field: 'datas_fname', id: data.id}); self.data[data.id] = data; }); + return ids; }); } else { - return $.when(); + return $.when(ids); } }, render_value: function () { var self = this; - this.read_name_values().then(function () { - - var render = $(instance.web.qweb.render('FieldBinaryFileUploader.files', {'widget': self})); + this.read_name_values().then(function (ids) { + var render = $(instance.web.qweb.render('FieldBinaryFileUploader.files', {'widget': self, 'values': ids})); render.on('click', '.oe_delete', _.bind(self.on_file_delete, self)); self.$('.oe_placeholder_files, .oe_attachments').replaceWith( render ); -- cgit v1.2.3 From d6c6f31231070213bfabf0afdadc7a45d6fd626a Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 2 Dec 2013 14:19:43 +0100 Subject: [MERGE] boostrap3 manually merged bzr revid: al@openerp.com-20131202131943-b01fb56u0qsgcs53 --- addons/web/static/src/js/chrome.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 56559e9edb9..abbd4767361 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -442,10 +442,10 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ self.$el.html(QWeb.render("DatabaseManager", { widget : self })); $('.oe_user_menu_placeholder').append(QWeb.render("DatabaseManager.user_menu",{ widget : self })); $('.oe_secondary_menus_container').append(QWeb.render("DatabaseManager.menu",{ widget : self })); - $('ul.oe_secondary_submenu > li:first').addClass('oe_active'); + $('ul.oe_secondary_submenu > li:first').addClass('active'); $('ul.oe_secondary_submenu > li').bind('click', function (event) { var menuitem = $(this); - menuitem.addClass('oe_active').siblings().removeClass('oe_active'); + menuitem.addClass('active').siblings().removeClass('active'); var form_id =menuitem.find('a').attr('href'); $(form_id).show().siblings().hide(); event.preventDefault(); @@ -969,7 +969,7 @@ instance.web.Menu = instance.web.Widget.extend({ this.needaction_data = data; _.each(this.needaction_data, function (item, menu_id) { var $item = self.$secondary_menus.find('a[data-menu="' + menu_id + '"]'); - $item.find('.oe_menu_counter').remove(); + $item.find('.badge').remove(); if (item.needaction_counter && item.needaction_counter > 0) { $item.append(QWeb.render("Menu.needaction_counter", { widget : item })); } @@ -982,8 +982,8 @@ instance.web.Menu = instance.web.Widget.extend({ reflow: function() { var self = this; this.$el.height('auto').show(); - var $more_container = this.$('.oe_menu_more_container').hide(); - var $more = this.$('.oe_menu_more'); + var $more_container = this.$('#menu_more_container').hide(); + var $more = this.$('#menu_more'); $more.children('li').insertBefore($more_container); var $toplevel_items = this.$el.children('li').not($more_container).hide(); $toplevel_items.each(function() { @@ -1026,8 +1026,8 @@ instance.web.Menu = instance.web.Widget.extend({ } // Activate current main menu - this.$el.find('.oe_active').removeClass('oe_active'); - $main_menu.addClass('oe_active'); + this.$el.find('.active').removeClass('active'); + $main_menu.addClass('active'); // Show current sub menu this.$secondary_menus.find('.oe_secondary_menu').hide(); @@ -1037,13 +1037,13 @@ instance.web.Menu = instance.web.Widget.extend({ this.$secondary_menus.parent('.oe_leftbar').toggle(!!$sub_menu.children().length); // Activate current menu item and show parents - this.$secondary_menus.find('.oe_active').removeClass('oe_active'); + this.$secondary_menus.find('.active').removeClass('active'); if ($main_menu !== $clicked_menu) { $clicked_menu.parents().show(); if ($clicked_menu.is('.oe_menu_toggler')) { $clicked_menu.toggleClass('oe_menu_opened').siblings('.oe_secondary_submenu:first').toggle(); } else { - $clicked_menu.parent().addClass('oe_active'); + $clicked_menu.parent().addClass('active'); } } }, @@ -1129,7 +1129,7 @@ instance.web.Menu = instance.web.Widget.extend({ }, on_menu_click: function(ev) { ev.preventDefault(); - var needaction = $(ev.target).is('div.oe_menu_counter'); + var needaction = $(ev.target).is('div#menu_counter'); this.menu_click($(ev.currentTarget).data('menu'), needaction); }, }); @@ -1143,7 +1143,7 @@ instance.web.UserMenu = instance.web.Widget.extend({ start: function() { var self = this; this._super.apply(this, arguments); - this.$el.on('click', '.oe_dropdown_menu li a[data-menu]', function(ev) { + this.$el.on('click', '.dropdown-menu li a[data-menu]', function(ev) { ev.preventDefault(); var f = self['on_menu_' + $(this).data('menu')]; if (f) { @@ -1304,7 +1304,7 @@ instance.web.Client = instance.web.Widget.extend({ self.action_manager.appendTo(self.$('.oe_application')); }, toggle_bars: function(value) { - this.$('tr:has(td.oe_topbar),.oe_leftbar').toggle(value); + this.$('tr:has(td.navbar),.oe_leftbar').toggle(value); }, has_uncommitted_changes: function() { return false; -- cgit v1.2.3 From 753cb318040fc29995f5397b63ad9cc42a03cd90 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 2 Dec 2013 15:22:40 +0100 Subject: [IMP] upgrade backbone to 1.1.0 bzr revid: al@openerp.com-20131202142240-ifh2rua2oiennfao --- addons/web/static/src/js/core.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index d62c04b0ecb..81e029f5f87 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -561,8 +561,8 @@ instance.web.TranslationDataBase.include({ }); /** Custom jQuery plugins */ +$.browser = $.browser || {}; if(navigator.appVersion.indexOf("MSIE") !== -1) { - $.browser = $.browser || {}; $.browser.msie = 1; } $.fn.getAttributes = function() { -- cgit v1.2.3 From 0dff8277ccb20c6673b2a3013d2cb3d6e330e56c Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 2 Dec 2013 16:10:37 +0100 Subject: [FIX] breakage due to backbone change: in 1.0+, this.reset() will call this.add() in 0.9, this.add would only be called if items were provided to reset(), changed in commit cf6e862. bzr revid: xmo@openerp.com-20131202151037-xxmvu5790p2jsxz6 --- addons/web/static/src/js/search.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index fcfcfb08f8e..83eaecd845a 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -71,7 +71,10 @@ my.SearchQuery = B.Collection.extend({ }, add: function (values, options) { options = options || {}; - if (!(values instanceof Array)) { + + if (!values) { + values = []; + } else if (!(values instanceof Array)) { values = [values]; } -- cgit v1.2.3 From ef08d834f639e4d8b9d1053df833067322d5ce14 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 2 Dec 2013 16:18:38 +0100 Subject: [IMP] add warning re. changed behavior of backbone which may be changed in the client bzr revid: xmo@openerp.com-20131202151838-z26qnz0xpt3tigrd --- addons/web/static/src/js/search.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 83eaecd845a..c3ef682bfcc 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -90,6 +90,10 @@ my.SearchQuery = B.Collection.extend({ } B.Collection.prototype.add.call(this, model, options); }, this); + // warning: in backbone 1.0+ add is supposed to return the added models, + // but here toggle may delegate to add and return its value directly. + // return value of neither seems actually used but should be tested + // before change, probably return this; }, toggle: function (value, options) { -- cgit v1.2.3 From da6fee2ac14ece790bf0610c226dee72bf292acb Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 2 Dec 2013 16:42:06 +0100 Subject: [FIX] session expired bzr revid: al@openerp.com-20131202154206-6efsbeeg0mq7s67z --- addons/web/static/src/js/chrome.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 3727b011943..7587cf006e3 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -256,7 +256,7 @@ instance.web.CrashManager = instance.web.Class.extend({ new (handler)(this, error).display(); return; } - if (error.data.name === "openerp.addons.web.session SessionExpiredException") { + if (error.data.name === "openerp.addons.web.http.SessionExpiredException") { this.show_warning({type: "Session Expired", data: { message: _t("Your OpenERP session expired. Please refresh the current web page.") }}); return; } -- cgit v1.2.3 From b3391cd7fef94c4e82b4330db37213c08740d055 Mon Sep 17 00:00:00 2001 From: "Mohammed Shekha (OpenERP)" Date: Tue, 3 Dec 2013 18:08:56 +0530 Subject: [FIX]Web: Fixed the issue of immediate update of many2one field when many2one object name has been changed from follow button popup, reloaded the record from database forcefull to update dataaset, do not call form-blur when follow button is clicked, also do not evict record when record is still not created. bzr revid: msh@openerp.com-20131203123856-gce4li1igo9k1mak --- addons/web/static/src/js/data.js | 9 +++++++++ addons/web/static/src/js/view_form.js | 7 +++++++ 2 files changed, 16 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index d497cf25343..e1290deac02 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -920,6 +920,15 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({ * @param {Object} id record to remove from the BDS's cache */ evict_record: function (id) { + // Don't evict records which haven't yet been saved: there is no more + // recent data on the server (and there potentially isn't any data), + // and this breaks the assumptions of other methods (that the data + // for new and altered records is both in the cache and in the to_write + // or to_create collection) + if (_(this.to_create.concat(this.to_write)).find(function (record) { + return record.id === id; })) { + return; + } for(var i=0, len=this.cache.length; i Date: Tue, 3 Dec 2013 14:29:37 +0100 Subject: [FIX] web: openerpframework.js: do not use _.str openerpframework.js can be used as standalone library (im_livechat uses it this way) and do not depend on underscore.string.js bzr revid: chs@openerp.com-20131203132937-ss7hx1gligzai5ch --- addons/web/static/src/js/openerpframework.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/openerpframework.js b/addons/web/static/src/js/openerpframework.js index 99d11b58ca9..ca046543861 100644 --- a/addons/web/static/src/js/openerpframework.js +++ b/addons/web/static/src/js/openerpframework.js @@ -1128,7 +1128,7 @@ openerp.Model = openerp.Class.extend({ kwargs = args; args = []; } - var call_kw = _.str.sprintf('/web/dataset/call_kw/%s/%s', this.name, method); + var call_kw = '/web/dataset/call_kw/' + this.name + '/' + method; return this.session().rpc(call_kw, { model: this.name, method: method, -- cgit v1.2.3 From 15547d9267178493a22074b20b68099eb5948abb Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 5 Dec 2013 11:07:10 +0100 Subject: [REF] refactors the event handling code and prepare the way for supporting col_groupby and groupby in the searchbar (addon web_graph) bzr revid: ged@openerp.com-20131205100710-5owdxv0m971ymwbs --- addons/web/static/src/js/search.js | 1 - 1 file changed, 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index fcfcfb08f8e..99df7c5b712 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -528,7 +528,6 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea resp(_(arguments).chain() .compact() .map(function (completion) { - console.log(completion); if (completion.length && completion[0].facet !== undefined) { completion[0].first = true; } -- cgit v1.2.3 From b4c121db712742894027c4dd4821a4ed6a0f3a3f Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 6 Dec 2013 13:44:31 +0100 Subject: [FIX] bad interaction of editable list with IME MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IME are ways to input language which can't trivially map to a keyboard (e.g. CJK language) with a standard-ish keyboard. For japanese IME this is done by entering text phonetically: text is entered in romaji and automatically converted to hiragana (or katakana) when it matches the transcription a japanese syllable (~phoneme?) e.g. to (と). The text is then split and reprocessed with sequences of hiragana being converted to kanji (or not), and the possibility to pick the right kanji when multiple kanji match e.g. for "Tokyo" toukyou -> とうきょう -> 東京. But to do the edition, keyboard keys are used. For the japanese IMEs (tested on Windows, OSX and Linux) [Space] will do the initial conversion from kana to kanji (and allow selecting an other conversion or a different kana split) and [Return] will validate the current conversion (removing the underline marking "unvalidated" kana or kanji groups). And that's where the problem hit: IME + browser combinations may or may not suppress part of all of the event. Firefox will trigger a keydown of the key which "starts" IME input (e.g. "t") and will trigger a keyup for the validation key (return), except on Linux where the initial keydown is suppressed. Inbetween these, it will fire no keydown, keyup or keypress event but will fire input events (at least on an input element) every time the displayed text changes. Meanwhile webkit browsers will, for each press on the keyboard during IME, * trigger a keydown with the keyCode 229 * trigger a keyup event with the keycode of the key which was actually hit * trigger input events every time the displayed text changes This include meta-operation uses of [Space] and [Return]. MSIE has the same behavior (including triggering the input event), but the keydown event is augmented with ``key`` and ``char`` attributes providing the character matching the key hit to trigger the change. Although the triggering of the input even is useless for the purpose of the editable list (especially here, the purpose of validating a list row with [Return] one fact stands out: keypress is never triggered during IME operations, hitting the [Return] key outside of IME will trigger keydow, keypress, keyup but doing so during IME will only trigger the first and last. Thus by changing the binding from keyup (return) to keypress (return) for a line validation, spurious validation during IME text entry should be avoided. This seems to work correctly on MSIE (Windows), Firefox (Windows, OSX, Linux), Chrome (Windows, OSX, Linux) and Safari (OSX), after testing in IE9, IE10, Chrome 31, Firefox 25 and Safari 7, and a quick test on a task's o2m did not reveal any regression. note: not all differences between various browser/os combinations were inspected in details, there may well be further differences which were not noticed or not relevant to this precise issue. bzr revid: xmo@openerp.com-20131206124431-q4a9l1gn9wjtmlvz --- addons/web/static/src/js/view_form.js | 2 +- addons/web/static/src/js/view_list_editable.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 080cd6f70aa..d91b9c93362 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -3980,7 +3980,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ } this.cancel_edition(); }, - keyup_ENTER: function () { + keypress_ENTER: function () { // blurring caused by hitting the [Return] key, should skip the // autosave-on-blur and let the handler for [Return] do its thing (save // the current row *anyway*, then create a new one/edit the next one) diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js index 512fc4ff373..0cf71660cef 100644 --- a/addons/web/static/src/js/view_list_editable.js +++ b/addons/web/static/src/js/view_list_editable.js @@ -451,7 +451,7 @@ openerp.web.list_editable = function (instance) { set_invisible(); }); - this.editor.$el.on('keyup keydown', function (e) { + this.editor.$el.on('keyup keypress keydown', function (e) { if (!self.editor.is_editing()) { return true; } var key = _($.ui.keyCode).chain() .map(function (v, k) { return {name: k, code: v}; }) @@ -485,7 +485,7 @@ openerp.web.list_editable = function (instance) { return self.start_edition(record, options); }); }, - keyup_ENTER: function () { + keypress_ENTER: function () { return this._next(); }, keydown_ESCAPE: function (e) { -- cgit v1.2.3 From 6a06f0d0eeee1efe7417d3a73eb2e4b8661d73d6 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 6 Dec 2013 16:43:19 +0100 Subject: [IMP] properly supports searchbar integration in graph view (addon web_graph) bzr revid: ged@openerp.com-20131206154319-6ci7ljmp2hd9q072 --- addons/web/static/src/js/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 99df7c5b712..56067707978 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -82,7 +82,7 @@ my.SearchQuery = B.Collection.extend({ && facet.get('field') === model.get('field'); }); if (previous) { - previous.values.add(model.get('values')); + previous.values.add(model.get('values'), options); return; } B.Collection.prototype.add.call(this, model, options); -- cgit v1.2.3 From 68aac8e85515f69b98492fd4c20a62004086595a Mon Sep 17 00:00:00 2001 From: Michel Meyer Date: Mon, 9 Dec 2013 16:35:19 +0100 Subject: [FIX] events handling ordering courtesy of Michel Meyer lead to errors during the validation of rows in list o2ms. See https://bugs.launchpad.net/openerp-web/+bug/1182101/comments/20 for an extensive description of the events and issue. bzr revid: xmo@openerp.com-20131209153519-n05bdx15t75dh7gf --- addons/web/static/src/js/view_form.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 080cd6f70aa..3893626520f 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -3822,7 +3822,6 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ GroupsType: instance.web.form.One2ManyGroups, ListType: instance.web.form.One2ManyList })); - this.on('edit:before', this, this.proxy('_before_edit')); this.on('edit:after', this, this.proxy('_after_edit')); this.on('save:before cancel:before', this, this.proxy('_before_unedit')); @@ -3943,11 +3942,10 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ }); }, - _before_edit: function () { + _after_edit: function () { this.__ignore_blur = false; this.editor.form.on('blurred', this, this._on_form_blur); - }, - _after_edit: function () { + // The form's blur thing may be jiggered during the edition setup, // potentially leading to the o2m instasaving the row. Cancel any // blurring triggered the edition startup here -- cgit v1.2.3 From 029c866b8c68a7eb15a04ee1e42fac7c69889aa4 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 10 Dec 2013 10:30:55 +0100 Subject: [FIX] issue when tabbing too much at end of editable list row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tabbing is intercepted by keydown_TAB, which — if the current cell is the last active field of the row — will then call _next:476. _next then calls save_edition:300 which "takes a lock" (more precisely serializes access to its body) and within its body checks if an edition is active (:303) and returns immediately if not (:304). The problem here is when a second tab event arrives during the potentially extremely long save_edition body (since for toplevel lists it needs to perform a complete RPC call): the overall state of the list has not changed so the second event *also* goes into _next, then into save_edition. There it's serialized with the ongoing call and thus inactive until said ongoing call's termination, and reaches the body after the current edition has been wound down. As a result, the body of _next (:408) gets the resolution of ``$.when()``, which is ``null`` and the first condition blows up. There are 3 possible ways to fix this: * adding a check in keydown_TAB's handler to see whether a _next call is ongoing. This requires adding a state flag to the object and does not protect (or cooperate with) _next calls from outside this specific handler, unless they are modified in turn. * alter save_edition to *fail* in case there's no ongoing edition: this part was originally in ensure_saved which does not care whether a save was necessary or not and does not propagate save information, so ``$.when()`` made sense. In save_edition, there are really 3 different outcomes: the save succeeded, the save failed (or potentially part of save's postprocessing failed, for the current implementation) and the save was unnecessary. But deferred only provide 1 bit of state (success or failure), so the last state has to be merged into either success or failure. Both make sense, to an extent. Changing from one to the other (as necessary here) could break existing code and have more extensive effects than expected. * the simplest and least far-raging change is to just alter the save_edition().then handler to ignore cases where save_edition() results in no saveinfo, this can be assumed to be a bailed-out/unnecessary save call. For simplicity, the 3rd solution was picked here although with more extensive tests &al I'd have preferred trying out 2nd. lp bug: https://launchpad.net/bugs/1253899 fixed bzr revid: xmo@openerp.com-20131210093055-207fevqc1npy7fwr --- addons/web/static/src/js/view_list_editable.js | 1 + 1 file changed, 1 insertion(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js index 512fc4ff373..f00296eec40 100644 --- a/addons/web/static/src/js/view_list_editable.js +++ b/addons/web/static/src/js/view_list_editable.js @@ -477,6 +477,7 @@ openerp.web.list_editable = function (instance) { next_record = next_record || 'succ'; var self = this; return this.save_edition().then(function (saveInfo) { + if (!saveInfo) { return null; } if (saveInfo.created) { return self.start_edition(); } -- cgit v1.2.3 From 9322b677aa7848ab6ece42786f46137ff7eea05c Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 10 Dec 2013 13:47:55 +0100 Subject: [FIX] weird behavior when drag&dropping a row during edition in editable listview MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When dropping, would simultanously stop the edition and try a write (so 2 writes on the same record) and generally screw up the state of all the things, ending up with an empty row and a weird (and incorrect) warning. This can be fixed by preventing resequencing during the creation or edition of a record (row) inline. For simplicity, implemented by looking up .ui-sortable descendants — there are no utility methods for handling that and, aside from the class, there's no good way to know if sortability was enabled on a list body or not (as far as I can see, jquery-ui's sortable has no API to query that) — and using jquery-ui's sortable API for enabling and disabling sortable on the fly. lp bug: https://launchpad.net/bugs/1257753 fixed bzr revid: xmo@openerp.com-20131210124755-ugr3ehf744qoh1o5 --- addons/web/static/src/js/view_list_editable.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js index f00296eec40..f2fd8974d81 100644 --- a/addons/web/static/src/js/view_list_editable.js +++ b/addons/web/static/src/js/view_list_editable.js @@ -50,8 +50,10 @@ openerp.web.list_editable = function (instance) { }); this.on('edit:after', this, function () { self.$el.add(self.$buttons).addClass('oe_editing'); + self.$('.ui-sortable').sortable('disable'); }); this.on('save:after cancel:after', this, function () { + self.$('.ui-sortable').sortable('enable'); self.$el.add(self.$buttons).removeClass('oe_editing'); }); }, -- cgit v1.2.3 From 762774df3749ae6c1205878f430f0d886c42ea55 Mon Sep 17 00:00:00 2001 From: xmo <> Date: Tue, 10 Dec 2013 16:57:03 +0100 Subject: [FIX] prevent field going to be misplaced when going from readonly to writable in editable list view bzr revid: mat@openerp.com-20131210155703-2mzqa2mch46nxpcj --- addons/web/static/src/js/view_list_editable.js | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js index f2fd8974d81..bd9cee06797 100644 --- a/addons/web/static/src/js/view_list_editable.js +++ b/addons/web/static/src/js/view_list_editable.js @@ -451,6 +451,13 @@ openerp.web.list_editable = function (instance) { field.on("change:effective_readonly", self, set_invisible); field.on("change:invisible", self, set_invisible); set_invisible(); + field.on('change:invisible', self, function () { + if (field.get('invisible')) { return; } + var item = _(self.fields_for_resize).find(function (item) { + return item.field === field; + }); + if (item) { self.resize_field(item.field, item.cell); } + }); }); this.editor.$el.on('keyup keydown', function (e) { -- cgit v1.2.3 From fec27404acc68beffeed82b9863cbe31d7287edf Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 10 Dec 2013 17:44:43 +0100 Subject: [CHG] replace [Add] button in m2m lists by link in row, similar to o2m Task 4941 Extracted relevant section from One2ManyList which already implemented it previously, then created and hooked in m2m list using (inheriting from) extracted code. bzr revid: xmo@openerp.com-20131210164443-ur44b8g5gdrt8jt1 --- addons/web/static/src/js/view_form.js | 135 ++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 57 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 683cdebbbf4..f20e9053867 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -3588,6 +3588,67 @@ instance.web.form.Many2OneButton = instance.web.form.AbstractField.extend({ }, }); +/** + * Abstract-ish ListView.List subclass adding an "Add an item" row to replace + * the big ugly button in the header. + * + * Requires the implementation of a ``is_readonly`` method (usually a proxy to + * the corresponding field's readonly or effective_readonly property) to + * decide whether the special row should or should not be inserted. + * + * Optionally an ``_add_row_class`` attribute can be set for the class(es) to + * set on the insertion row. + */ +instance.web.form.AddAnItemList = instance.web.ListView.List.extend({ + pad_table_to: function (count) { + if (!this.view.is_action_enabled('create') || this.is_readonly()) { + this._super(count); + return; + } + + this._super(count > 0 ? count - 1 : 0); + + var self = this; + var columns = _(this.columns).filter(function (column) { + return column.invisible !== '1'; + }).length; + if (this.options.selectable) { columns++; } + if (this.options.deletable) { columns++; } + + var $cell = $('', { + colspan: columns, + 'class': this._add_row_class || '' + }).append( + $('', {href: '#'}).text(_t("Add an item")) + .mousedown(function () { + // FIXME: needs to be an official API somehow + if (self.view.editor.is_editing()) { + self.view.__ignore_blur = true; + } + }) + .click(function (e) { + e.preventDefault(); + e.stopPropagation(); + // FIXME: there should also be an API for that one + if (self.view.editor.form.__blur_timeout) { + clearTimeout(self.view.editor.form.__blur_timeout); + self.view.editor.form.__blur_timeout = false; + } + self.view.ensure_saved().done(function () { + self.view.do_add_record(); + }); + })); + + var $padding = this.$current.find('tr:not([data-id]):first'); + var $newrow = $('').append($cell); + if ($padding.length) { + $padding.before($newrow); + } else { + this.$current.append($newrow) + } + } +}); + /* # Values: (0, 0, { fields }) create # (1, ID, { fields }) update @@ -4166,62 +4227,11 @@ instance.web.form.One2ManyGroups = instance.web.ListView.Groups.extend({ } } }); -instance.web.form.One2ManyList = instance.web.ListView.List.extend({ - pad_table_to: function (count) { - if (!this.view.is_action_enabled('create')) { - this._super(count); - } else { - this._super(count > 0 ? count - 1 : 0); - } - - // magical invocation of wtf does that do - if (this.view.o2m.get('effective_readonly')) { - return; - } - - var self = this; - var columns = _(this.columns).filter(function (column) { - return column.invisible !== '1'; - }).length; - if (this.options.selectable) { columns++; } - if (this.options.deletable) { columns++; } - - if (!this.view.is_action_enabled('create')) { - return; - } - - var $cell = $('', { - colspan: columns, - 'class': 'oe_form_field_one2many_list_row_add' - }).append( - $('', {href: '#'}).text(_t("Add an item")) - .mousedown(function () { - // FIXME: needs to be an official API somehow - if (self.view.editor.is_editing()) { - self.view.__ignore_blur = true; - } - }) - .click(function (e) { - e.preventDefault(); - e.stopPropagation(); - // FIXME: there should also be an API for that one - if (self.view.editor.form.__blur_timeout) { - clearTimeout(self.view.editor.form.__blur_timeout); - self.view.editor.form.__blur_timeout = false; - } - self.view.ensure_saved().done(function () { - self.view.do_add_record(); - }); - })); - - var $padding = this.$current.find('tr:not([data-id]):first'); - var $newrow = $('').append($cell); - if ($padding.length) { - $padding.before($newrow); - } else { - this.$current.append($newrow); - } - } +instance.web.form.One2ManyList = instance.web.form.AddAnItemList.extend({ + _add_row_class: 'oe_form_field_one2many_list_row_add', + is_readonly: function () { + return this.view.o2m.get('effective_readonly'); + }, }); instance.web.form.One2ManyFormView = instance.web.FormView.extend({ @@ -4433,7 +4443,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend(instan this.$el.addClass('oe_form_field oe_form_field_many2many'); this.list_view = new instance.web.form.Many2ManyListView(this, this.dataset, false, { - 'addable': this.get("effective_readonly") ? null : _t("Add"), + 'addable': null, 'deletable': this.get("effective_readonly") ? false : true, 'selectable': this.multi_selection, 'sortable': false, @@ -4500,6 +4510,11 @@ instance.web.form.Many2ManyDataSet = instance.web.DataSetStatic.extend({ * @extends instance.web.ListView */ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends instance.web.form.Many2ManyListView# */{ + init: function (parent, dataset, view_id, options) { + this._super(parent, dataset, view_id, _.extend(options || {}, { + ListType: instance.web.form.Many2ManyList, + })); + }, do_add_record: function () { var pop = new instance.web.form.SelectCreatePopup(this); pop.select_element( @@ -4549,6 +4564,12 @@ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends in }, is_action_enabled: function () { return true; }, }); +instance.web.form.Many2ManyList = instance.web.form.AddAnItemList.extend({ + _add_row_class: 'oe_form_field_many2many_list_row_add', + is_readonly: function () { + return this.view.m2m_field.get('effective_readonly'); + } +}); instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend(instance.web.form.CompletionFieldMixin, { disable_utility_classes: true, -- cgit v1.2.3 From 920ba459353d13946c2bde804fb64c8e146b15cf Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 11 Dec 2013 17:18:10 +0100 Subject: [FIX] filter the context keys only on the result action of the button bzr revid: chs@openerp.com-20131211161810-hetgizet5mv3xkys --- addons/web/static/src/js/views.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 1ee89238e7d..517a6ced723 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -1355,20 +1355,19 @@ instance.web.View = instance.web.Widget.extend({ return self.getParent().on_action_executed.apply(null, arguments); } }; - var context = dataset.get_context(); - if (action_data.model !== dataset.model) { - // filter out context keys that are specific to the action model. - // Wrong default_ and search_default values will no give the expected views - // Wrong group_by values will simply fail and forbid rendering of the destination view - context = _.object(_.reject(_.pairs(context.eval()), function(pair) { - return pair[0].match('^(?:(?:default_|search_default_).+|group_by|group_by_no_leaf)$') !== null; - })); - } + var context = new instance.web.CompoundContext(dataset.get_context(), action_data.context || {}); - context = new instance.web.CompoundContext(context, action_data.context || {}); + // response handler var handler = function (action) { if (action && action.constructor == Object) { - var ncontext = new instance.web.CompoundContext(context); + // filter out context keys that are specific to the current action. + // Wrong default_* and search_default_* values will no give the expected result + // Wrong group_by values will simply fail and forbid rendering of the destination view + var ncontext = new instance.web.CompoundContext( + _.object(_.reject(_.pairs(context.eval()), function(pair) { + return pair[0].match('^(?:(?:default_|search_default_).+|group_by|group_by_no_leaf)$') !== null; + })) + ); if (record_id) { ncontext.add({ active_id: record_id, -- cgit v1.2.3 From 9241d5f6993a662c1bc194f828cf39f4c04efb7a Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 11 Dec 2013 17:36:09 +0100 Subject: [FIX] when executing action received from a button call, set active_id and active_ids if there is one, remove existing if not; always set active_model bzr revid: chs@openerp.com-20131211163609-i3s2mlncf5n91uda --- addons/web/static/src/js/views.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 517a6ced723..1d7ed406378 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -1365,14 +1365,14 @@ instance.web.View = instance.web.Widget.extend({ // Wrong group_by values will simply fail and forbid rendering of the destination view var ncontext = new instance.web.CompoundContext( _.object(_.reject(_.pairs(context.eval()), function(pair) { - return pair[0].match('^(?:(?:default_|search_default_).+|group_by|group_by_no_leaf)$') !== null; + return pair[0].match('^(?:(?:default_|search_default_).+|group_by|group_by_no_leaf|active_id|active_ids)$') !== null; })) ); + ncontext.add({active_model: dataset.model}); if (record_id) { ncontext.add({ active_id: record_id, active_ids: [record_id], - active_model: dataset.model }); } ncontext.add(action.context || {}); -- cgit v1.2.3 From 0fd50c4750a5ca336954c5c6e4ca1fe414bd42aa Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 13 Dec 2013 10:35:42 +0100 Subject: [REM] leftover logging bzr revid: xmo@openerp.com-20131213093542-sdomq8skpwq5wrgv --- addons/web/static/src/js/search.js | 1 - 1 file changed, 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index c3ef682bfcc..45170e08a96 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -535,7 +535,6 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea resp(_(arguments).chain() .compact() .map(function (completion) { - console.log(completion); if (completion.length && completion[0].facet !== undefined) { completion[0].first = true; } -- cgit v1.2.3 From 56a78ab3a49e34c66e6e4c01e12729cb3356d166 Mon Sep 17 00:00:00 2001 From: Vidhin Mehta Date: Tue, 17 Dec 2013 13:00:42 +0530 Subject: [FIX]Issue of trunk in website branch. bzr revid: vme@tinyerp.com-20131217073042-13d3aa7vgct4l3xw --- addons/web/static/src/js/view_list.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 17c62917a18..ab1192f7f52 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -1130,11 +1130,7 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web. if (column.invisible === '1') { return; } - if (column.tag === 'button') { - cells.push(' '); - } else { - cells.push(' '); - } + cells.push(' '); }); if (this.options.deletable) { cells.push(''); -- cgit v1.2.3 From cfd24d982295af13ac6c90f2882e7e49e754c8f3 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 17 Dec 2013 11:41:11 +0100 Subject: [FIX] view_list_editable: toggle visibility (using force_visibility attribute) for readonly changes, using effective_invisibility instead of invisibility attribute (opw 601970) bzr revid: mat@openerp.com-20131217104111-u9bnqvz7rd5rzwnc --- addons/web/static/src/js/view_list_editable.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js index bd9cee06797..4c7e4655054 100644 --- a/addons/web/static/src/js/view_list_editable.js +++ b/addons/web/static/src/js/view_list_editable.js @@ -274,7 +274,7 @@ openerp.web.list_editable = function (instance) { if (!this.editor.is_editing()) { return; } for(var i=0, len=this.fields_for_resize.length; i Date: Wed, 18 Dec 2013 12:24:16 +0100 Subject: [FIX] web: context propagation was broken on buttons of action and object type. The context on the button must be propagated to the resulting action bzr revid: dle@openerp.com-20131218112416-2vtaq442qo8opq4u --- addons/web/static/src/js/views.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 1d7ed406378..c9584002472 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -1364,10 +1364,11 @@ instance.web.View = instance.web.Widget.extend({ // Wrong default_* and search_default_* values will no give the expected result // Wrong group_by values will simply fail and forbid rendering of the destination view var ncontext = new instance.web.CompoundContext( - _.object(_.reject(_.pairs(context.eval()), function(pair) { + _.object(_.reject(_.pairs(dataset.get_context().eval()), function(pair) { return pair[0].match('^(?:(?:default_|search_default_).+|group_by|group_by_no_leaf|active_id|active_ids)$') !== null; })) ); + ncontext.add(action_data.context || {}); ncontext.add({active_model: dataset.model}); if (record_id) { ncontext.add({ -- cgit v1.2.3 From 9491755b8b4116758afbbefd675660c3b05fd289 Mon Sep 17 00:00:00 2001 From: Xavier ALT Date: Wed, 18 Dec 2013 12:35:47 +0100 Subject: [FIX] web: only show in 'Advanced Search', fields that are actually searcheable and avoid duplicate 'ID' field bzr revid: xal@openerp.com-20131218113547-myl7eihvw5vbzkaa --- addons/web/static/src/js/search.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 78f53506abc..1b3d85930e6 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -1848,9 +1848,14 @@ instance.web.search.Advanced = instance.web.search.Input.extend({ new instance.web.Model(this.view.model).call('fields_get', { context: this.view.dataset.context }).done(function(data) { - self.fields = _.extend({ + self.fields = { id: { string: 'ID', type: 'id' } - }, data); + }; + _.each(data, function(field_def, field_name) { + if (field_def.selectable !== false && field_name != 'id') { + self.fields[field_name] = field_def; + } + }); })).done(function () { self.append_proposition(); }); -- cgit v1.2.3 From 5d3891835b87bbc34283e6ea8112c57e1aaa6f0b Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 19 Dec 2013 14:04:45 +0100 Subject: [ADD] Client.client_options bzr revid: fme@openerp.com-20131219130445-tvola5kfm86b3blf --- addons/web/static/src/js/chrome.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index abbd4767361..f87e662dd90 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -659,7 +659,7 @@ instance.web.Login = instance.web.Widget.extend({ this._super(parent); this.has_local_storage = typeof(localStorage) != 'undefined'; this.db_list = null; - this.selected_db = null; + this.selected_db = this.client_options.dbname || null; this.selected_login = null; this.params = action.params || {}; if (_.isEmpty(this.params)) { @@ -1246,6 +1246,7 @@ instance.web.FullscreenWidget = instance.web.Widget.extend({ instance.web.Client = instance.web.Widget.extend({ init: function(parent, origin) { instance.client = instance.webclient = this; + this.client_options = {}; this._super(parent); this.origin = origin; }, @@ -1316,8 +1317,11 @@ instance.web.WebClient = instance.web.Client.extend({ events: { 'click .oe_logo_edit_admin': 'logo_edit' }, - init: function(parent) { + init: function(parent, client_options) { this._super(parent); + if (client_options) { + _.extend(this.client_options, client_options); + } this._current_state = null; this.menu_dm = new instance.web.DropMisordered(); this.action_mutex = new $.Mutex(); -- cgit v1.2.3 From 6754d72a93bed5607a7afd56fcc60fc99fce71cc Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 19 Dec 2013 14:46:01 +0100 Subject: [FIX] webclient reference bzr revid: fme@openerp.com-20131219134601-9lgi8d3x7e02umoq --- addons/web/static/src/js/chrome.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index f87e662dd90..90d13f0a67e 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -659,7 +659,7 @@ instance.web.Login = instance.web.Widget.extend({ this._super(parent); this.has_local_storage = typeof(localStorage) != 'undefined'; this.db_list = null; - this.selected_db = this.client_options.dbname || null; + this.selected_db = instance.webclient.client_options.dbname || null; this.selected_login = null; this.params = action.params || {}; if (_.isEmpty(this.params)) { -- cgit v1.2.3 From 90b63ee28c398f526148801e79a6081d34a538c5 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 19 Dec 2013 19:06:28 +0100 Subject: [FIX] support client_options.action and client_options.post_login_action bzr revid: fme@openerp.com-20131219180628-s95y5ryomnbgvko2 --- addons/web/static/src/js/chrome.js | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 90d13f0a67e..7d54efdfe7d 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1340,6 +1340,10 @@ instance.web.WebClient = instance.web.Client.extend({ } else { self.show_application(); } + if (self.client_options.action) { + self.action_manager.do_action(self.client_options.action); + delete(self.client_options.action); + } }); }, to_kitten: function() { @@ -1422,6 +1426,10 @@ instance.web.WebClient = instance.web.Client.extend({ self.bind_hashchange(); self.set_title(); self.check_timezone(); + if (self.client_options.action_post_login) { + self.action_manager.do_action(self.client_options.action_post_login); + delete(self.client_options.action_post_login); + } }, update_logo: function() { var img = this.session.url('/web/binary/company_logo'); -- cgit v1.2.3 From 1bb2fccb9d92e76e8a0f1c99ebbd27cb30618444 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 7 Jan 2014 17:11:54 +0100 Subject: [FIX] web: avoid crash when the Home client action is called without `action` param E.g. this could happen when the HistoryBack client action was unable to restore the previous breadcrumbs item, and used the Home action as fallback. Could be reproduce by performing a successful import from an action without menu and context, such as what you get after refreshing your browser. bzr revid: odo@openerp.com-20140107161154-430y7hlf9mvtfyfe --- addons/web/static/src/js/chrome.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index c9128683f83..b51f86ba195 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -819,7 +819,7 @@ instance.web.client_actions.add("history_back", "instance.web.HistoryBack"); */ instance.web.Home = function(parent, action) { var url = '/' + (window.location.search || ''); - instance.web.redirect(url, action.params && action.params.wait); + instance.web.redirect(url, action && action.params && action.params.wait); }; instance.web.client_actions.add("home", "instance.web.Home"); -- cgit v1.2.3 From 98bd9a3fc3544ab7c99bedc346a993705b1376f1 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 10 Jan 2014 16:48:12 +0100 Subject: [FIX] the SearchQuery.add methods now properly removes the 'at' and 'merge' keys before propagating options, so the tests should now pass (addon web) bzr revid: ged@openerp.com-20140110154812-kazqirnie3kwtl4m --- addons/web/static/src/js/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 9c713e07669..2585b3829bd 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -85,7 +85,7 @@ my.SearchQuery = B.Collection.extend({ && facet.get('field') === model.get('field'); }); if (previous) { - previous.values.add(model.get('values'), options); + previous.values.add(model.get('values'), _.omit(options, 'at', 'merge')); return; } B.Collection.prototype.add.call(this, model, options); -- cgit v1.2.3 From cc553cc507e3ce2356dbf46c0fe9656fc7289b89 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 13 Jan 2014 18:23:47 +0100 Subject: [FIX] format: trying to format an undefined value as the same effect as a value to false or infinity: return value_if_empty parameter bzr revid: mat@openerp.com-20140113172347-00anf6lh2jxin84w --- addons/web/static/src/js/formats.js | 1 + 1 file changed, 1 insertion(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 854c5f76218..998855c5bd4 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -142,6 +142,7 @@ instance.web.format_value = function (value, descriptor, value_if_empty) { } console.warn('Field', descriptor, 'had an empty string as value, treating as false...'); case false: + case undefined: case Infinity: case -Infinity: return value_if_empty === undefined ? '' : value_if_empty; -- cgit v1.2.3 From 75e02860c25efa49228df411c3656b6a0d3861f1 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 13 Jan 2014 18:38:08 +0100 Subject: [REM] Removed Login from webclient bzr revid: fme@openerp.com-20140113173808-1clqlztx6fs79h2k --- addons/web/static/src/js/chrome.js | 220 +++---------------------------------- addons/web/static/src/js/core.js | 2 +- 2 files changed, 17 insertions(+), 205 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 7d54efdfe7d..caac5c394ae 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -475,19 +475,6 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ this.$el.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login').unbind('click').end().empty(); this._super(); }, - /** - * Converts a .serializeArray() result into a dict. Does not bother folding - * multiple identical keys into an array, last key wins. - * - * @param {Array} array - */ - to_object: function (array) { - var result = {}; - _(array).each(function (record) { - result[record.name] = record.value; - }); - return result; - }, /** * Blocks UI and replaces $.unblockUI by a noop to prevent third parties * from unblocking the UI @@ -525,25 +512,11 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ var self = this; var fields = $(form).serializeArray(); self.rpc("/web/database/create", {'fields': fields}).done(function(result) { - var form_obj = self.to_object(fields); - var client_action = { - type: 'ir.actions.client', - tag: 'login', - params: { - 'db': form_obj['db_name'], - 'login': 'admin', - 'password': form_obj['create_admin_pwd'], - 'login_successful': function() { - var url = '/web?db=' + form_obj['db_name']; - if (self.session.debug) { - url += '&debug'; - } - instance.web.redirect(url); - }, - }, - _push_me: false, - }; - self.do_action(client_action); + if (result) { + instance.web.redirect('/web') + } else { + alert("Failed to create database"); + } }); }, do_duplicate: function(form) { @@ -641,156 +614,20 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ }, do_exit: function () { this.$el.remove(); - instance.webclient.show_login(); + instance.web.redirect('/web'); } }); instance.web.client_actions.add("database_manager", "instance.web.DatabaseManager"); -instance.web.Login = instance.web.Widget.extend({ - template: "Login", - remember_credentials: true, - events: { - 'change input[name=db],select[name=db]': function(ev) { - this.set('database_selector', $(ev.currentTarget).val()); - }, - }, - - init: function(parent, action) { - this._super(parent); - this.has_local_storage = typeof(localStorage) != 'undefined'; - this.db_list = null; - this.selected_db = instance.webclient.client_options.dbname || null; - this.selected_login = null; - this.params = action.params || {}; - if (_.isEmpty(this.params)) { - this.params = $.bbq.getState(true); - } - if (action && action.params && action.params.db) { - this.params.db = action.params.db; - } else if ($.deparam.querystring().db) { - this.params.db = $.deparam.querystring().db; - } - if (this.params.db) { - this.selected_db = this.params.db; - } - - if (this.params.login_successful) { - this.on('login_successful', this, this.params.login_successful); - } - // some cleanup to remove any trace of that last login feature - if (typeof(localStorage) != 'undefined') { - var toRemove = []; - _.each(_.range(localStorage.length), function(i) { - var key = localStorage.key(i); - if (key.match(/^.*?\|last_password$/)) { - toRemove.push(key); - } - }); - _.each(toRemove, function(k) { - localStorage.removeItem(k); - }); - } - }, - start: function() { - var self = this; - self.$el.find("form").submit(self.on_submit); - self.$el.find('.oe_login_manage_db').click(function() { - self.do_action("database_manager"); - }); - self.on('change:database_selector', this, function() { - this.database_selected(this.get('database_selector')); - }); - var d = $.when(); - if ($.param.fragment().token) { - self.params.token = $.param.fragment().token; - } - // used by dbmanager.do_create via internal client action - if (self.params.db && self.params.login && self.params.password) { - d = self.do_login(self.params.db, self.params.login, self.params.password); - } else { - d = self.rpc("/web/database/get_list", {}) - .done(self.on_db_loaded) - .fail(self.on_db_failed) - .always(function() { - if (self.selected_db && self.has_local_storage && self.remember_credentials) { - self.$("[name=login]").val(localStorage.getItem(self.selected_db + '|last_login') || ''); - } - }); - } - return d; - }, - database_selected: function(db) { - var params = $.deparam.querystring(); - params.db = db; - this.$('.oe_login_dbpane').empty().text(_t('Loading...')); - this.$('[name=login], [name=password]').prop('readonly', true); - instance.web.redirect('/web?' + $.param(params)); - }, - on_db_loaded: function (result) { - var self = this; - this.db_list = result; - if (!this.selected_db) { - this.selected_db = result[0]; - } - this.$("[name=db]").replaceWith(QWeb.render('Login.dblist', { db_list: this.db_list, selected_db: this.selected_db})); - if(this.db_list.length === 0) { - this.do_action("database_manager"); - } else if(this.db_list.length === 1) { - this.$('div.oe_login_dbpane').hide(); - } else { - this.$('div.oe_login_dbpane').show(); - } - }, - on_db_failed: function (error, event) { - if (error.data.name === 'openerp.exceptions.AccessDenied') { - event.preventDefault(); - } - }, - on_submit: function(ev) { - if(ev) { - ev.preventDefault(); - } - var db = this.$("form [name=db]").val(); - if (!db) { - this.do_warn(_t("Login"), _t("No database selected !")); - return false; - } - var login = this.$("form input[name=login]").val(); - var password = this.$("form input[name=password]").val(); +instance.web.login = function() { + instance.web.redirect('/web/login'); +}; +instance.web.client_actions.add("login", "instance.web.login"); - this.do_login(db, login, password); - }, - /** - * Performs actual login operation, and UI-related stuff - * - * @param {String} db database to log in - * @param {String} login user login - * @param {String} password user password - */ - do_login: function (db, login, password) { - var self = this; - self.hide_error(); - self.$(".oe_login_pane").fadeOut("slow"); - return this.session.session_authenticate(db, login, password).then(function() { - if (self.has_local_storage && self.remember_credentials) { - localStorage.setItem(db + '|last_login', login); - } - self.trigger('login_successful'); - }, function () { - self.$(".oe_login_pane").fadeIn("fast", function() { - self.show_error(_t("Invalid username or password")); - }); - }); - }, - show_error: function(message) { - this.$el.addClass("oe_login_invalid"); - this.$(".oe_login_error_message").text(message); - }, - hide_error: function() { - this.$el.removeClass('oe_login_invalid'); - }, -}); -instance.web.client_actions.add("login", "instance.web.Login"); +instance.web.logout = function() { + instance.web.redirect('/web/session/logout'); +}; +instance.web.client_actions.add("logout", "instance.web.logout"); /** @@ -1335,9 +1172,7 @@ instance.web.WebClient = instance.web.Client.extend({ if (jQuery.deparam !== undefined && jQuery.deparam(jQuery.param.querystring()).kitten !== undefined) { self.to_kitten(); } - if (!self.session.session_is_valid()) { - self.show_login(); - } else { + if (self.session.session_is_valid()) { self.show_application(); } if (self.client_options.action) { @@ -1393,25 +1228,6 @@ instance.web.WebClient = instance.web.Client.extend({ }); }; }, - show_login: function() { - this.toggle_bars(false); - - var state = $.bbq.getState(true); - var action = { - type: 'ir.actions.client', - tag: 'login', - _push_me: false, - }; - - this.action_manager.do_action(action); - this.action_manager.inner_widget.on('login_successful', this, function() { - if ('redirect' in state) { - openerp.web.redirect(state.redirect); - } else { - this.show_application(); // will load the state we just pushed - } - }); - }, show_application: function() { var self = this; self.toggle_bars(true); @@ -1510,11 +1326,7 @@ instance.web.WebClient = instance.web.Client.extend({ on_logout: function() { var self = this; if (!this.has_uncommitted_changes()) { - this.session.session_logout().done(function () { - $(window).unbind('hashchange', self.on_hashchange); - self.do_push_state({}); - window.location.reload(); - }); + self.action_manager.do_action('logout'); } }, bind_hashchange: function() { diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 81e029f5f87..b92ca1d3ba5 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -252,7 +252,7 @@ instance.web.Session.include( /** @lends instance.web.Session# */{ return !!this.uid; }, /** - * The session is validated either by login or by restoration of a previous session + * The session is validated by restoration of a previous session */ session_authenticate: function() { var self = this; -- cgit v1.2.3 From f9b6ff07609995a1264d02624e53b82403c393cb Mon Sep 17 00:00:00 2001 From: jke-openerp Date: Mon, 13 Jan 2014 18:43:38 +0100 Subject: [REF] Refactoring according to the review of CHS bzr revid: jke@openerp.com-20140113174338-4fkx4zs8cw6k20y3 --- addons/web/static/src/js/views.js | 1 + 1 file changed, 1 insertion(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 25a424394bb..82a2095bace 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -331,6 +331,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ action_menu_id: null, additional_context: {}, }); + if (action === false) { action = { type: 'ir.actions.act_window_close' }; } else if (_.isString(action) && instance.web.client_actions.contains(action)) { -- cgit v1.2.3 From 9a84e25342d30efc79b1ce333bd4682c7b1b967f Mon Sep 17 00:00:00 2001 From: Xavier ALT Date: Tue, 14 Jan 2014 11:04:39 +0100 Subject: [FIX] web: list view: keep original fields.reference value instact, store it's display in fake field_name+'__display' column, so that editing value in editable tree mode works bzr revid: xal@openerp.com-20140114100439-hvdu9cxwyb3vvsum --- addons/web/static/src/js/view_list.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index ad48a8af1ef..ea37775038a 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -1022,7 +1022,7 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web. id = parseInt(ref_match[2], 10); new instance.web.DataSet(this.view, model).name_get([id]).done(function(names) { if (!names.length) { return; } - record.set(column.id, names[0][1]); + record.set(column.id + '__display', names[0][1]); }); } } else if (column.type === 'many2one') { @@ -2095,6 +2095,7 @@ instance.web.list.columns = new instance.web.Registry({ 'field.handle': 'instance.web.list.Handle', 'button': 'instance.web.list.Button', 'field.many2onebutton': 'instance.web.list.Many2OneButton', + 'field.reference': 'instance.web.list.Reference', 'field.many2many': 'instance.web.list.Many2Many' }); instance.web.list.columns.for_ = function (id, field, node) { @@ -2307,5 +2308,19 @@ instance.web.list.Many2Many = instance.web.list.Column.extend({ return this._super(row_data, options); } }); +instance.web.list.Reference = instance.web.list.Column.extend({ + _format: function (row_data, options) { + if (!_.isEmpty(row_data[this.id].value)) { + // If value, use __display version for printing + //console.log('_format', row_data[this.id], row_data[this.id + '__display']); + if (!!row_data[this.id + '__display']) { + row_data[this.id] = row_data[this.id + '__display']; + } else { + row_data[this.id] = {'value': ''}; + } + } + return this._super(row_data, options); + } +}); }; // vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: -- cgit v1.2.3 From 01f3648d3a6ab2b91ae8393860f0562dd46a44e9 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Tue, 14 Jan 2014 12:17:07 +0100 Subject: [ADD] javascript hooks for LoginForm and debug forwarding bzr revid: fme@openerp.com-20140114111707-ts3ik25p4o2vysxb --- addons/web/static/src/js/chrome.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index caac5c394ae..359b4201921 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1483,6 +1483,24 @@ instance.web.embed = function (origin, dbname, login, key, action, options) { client.insertAfter(currentScript); }; +openerp.web.LoginForm = openerp.web.Widget.extend({ + init: function ($form) { + this._super(/* no parent */); + this.setElement($form); + this.$el.on('submit', this.on_submit); + this.start(); + }, + start: function () { + if (location.hash) { + this.$el.attr('action', this.$el.attr('action') + location.hash); + } + return this._super(); + }, + on_submit: function () { + return true; + }, +}); + })(); // vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: -- cgit v1.2.3 From 3f4c6376745e937002c357b8b1c927ea990c4aa7 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 14 Jan 2014 15:57:20 +0100 Subject: [IMP] view_form: do not display hugly error message when name_get returns no value but more helpful message (eg: bad default value returns wrong id) bzr revid: mat@openerp.com-20140114145720-r3lg0qjezqj4p3i1 --- addons/web/static/src/js/view_form.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 148c79b3efd..e46f63b4d44 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -3299,6 +3299,10 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc if (! no_recurse) { var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context()); this.alive(dataset.name_get([self.get("value")])).done(function(data) { + if (!data[0]) { + self.do_warn(_t("Render"), _t("No value found for the field "+self.field.string+" for value "+self.get("value"))); + return; + } self.display_value["" + self.get("value")] = data[0][1]; self.render_value(true); }); -- cgit v1.2.3 From 6109102e91f5383a49d454c1ce2e3d1f37c75bfc Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Wed, 15 Jan 2014 13:08:44 +0100 Subject: [FIX] web: view_form.js, allow press enter to break line in fieldtextwidget bzr revid: dle@openerp.com-20140115120844-1z0pbh9pc63tllce --- addons/web/static/src/js/view_form.js | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index e46f63b4d44..738a9af5b40 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -2612,6 +2612,11 @@ instance.web.form.FieldText = instance.web.form.AbstractField.extend(instance.we e.stopPropagation(); } }, + 'keypress': function (e) { + if (e.which === $.ui.keyCode.ENTER) { + e.stopPropagation(); + } + }, 'change textarea': 'store_dom_value', }, initialize_content: function() { -- cgit v1.2.3 From 2dc722ac8071db832dc0d6b71f5824091aea2e83 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 17 Jan 2014 19:31:41 +0800 Subject: [FIX] format_value: consider text fields te same way as char fields for empty values bzr revid: mat@openerp.com-20140117113141-i95ncy04azzmahqk --- addons/web/static/src/js/formats.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 998855c5bd4..dd0a9040b6b 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -137,7 +137,7 @@ instance.web.format_value = function (value, descriptor, value_if_empty) { //noinspection FallthroughInSwitchStatementJS switch (value) { case '': - if (descriptor.type === 'char') { + if (descriptor.type === 'char' || descriptor.type === 'text') { return ''; } console.warn('Field', descriptor, 'had an empty string as value, treating as false...'); -- cgit v1.2.3 From 263693e44e9ee1dbb7b79b4eb83abba59d36f84a Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 20 Jan 2014 17:01:47 +0100 Subject: [FIX] search: add delay of 250us (was 0) on autocomplete fields in search bar and m2o fields. This avoids making a search request for each keypressed bzr revid: mat@openerp.com-20140120160147-q7lg4j93c836ec44 --- addons/web/static/src/js/search.js | 2 +- addons/web/static/src/js/view_form.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 1b3d85930e6..557d0baa124 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -476,7 +476,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea html: true, autoFocus: true, minLength: 1, - delay: 0, + delay: 250, }).data('autocomplete'); // MonkeyPatch autocomplete instance diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 738a9af5b40..a1813621977 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -3277,7 +3277,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc // disabled to solve a bug, but may cause others //close: anyoneLoosesFocus, minLength: 0, - delay: 0 + delay: 250 }); this.$input.autocomplete("widget").openerpClass(); // used to correct a bug when selecting an element by pushing 'enter' in an editable list -- cgit v1.2.3 From 9a0a02060fa048ce92ee0dab1bfbdcff63573237 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 21 Jan 2014 11:27:25 -0200 Subject: [FIX] format_value: when formating to date, make sure not converting from a datetime string as would make timezones apply and lead to a possible day change bzr revid: mat@openerp.com-20140121132725-k9f8hna3lg7nq7g8 --- addons/web/static/src/js/formats.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index dd0a9040b6b..640d919f4c1 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -191,6 +191,9 @@ instance.web.format_value = function (value, descriptor, value_if_empty) { + ' ' + normalize_format(l10n.time_format)); case 'date': if (typeof(value) == "string") + if (value.length > 10) + // in case value is a datetime, strip to avoid time manipulation + value = value.substring(0,10); value = instance.web.auto_str_to_date(value); return value.toString(normalize_format(l10n.date_format)); case 'time': -- cgit v1.2.3 From 36048a8442c89cf4f5811850c3e2c91d6eb862c7 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 21 Jan 2014 11:50:58 -0200 Subject: [IMP] always apply substring and call directly str_to_date bzr revid: mat@openerp.com-20140121135058-cr3ivak97rqm6npo --- addons/web/static/src/js/formats.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 640d919f4c1..58a785b6083 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -191,10 +191,9 @@ instance.web.format_value = function (value, descriptor, value_if_empty) { + ' ' + normalize_format(l10n.time_format)); case 'date': if (typeof(value) == "string") - if (value.length > 10) - // in case value is a datetime, strip to avoid time manipulation - value = value.substring(0,10); - value = instance.web.auto_str_to_date(value); + // in case value is a datetime, strip to avoid time manipulation + value = value.substring(0,10); + value = instance.web.str_to_date(value); return value.toString(normalize_format(l10n.date_format)); case 'time': if (typeof(value) == "string") -- cgit v1.2.3 From 3c3ab07e2fefdff743faf8ecffaf58e90c813c95 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 21 Jan 2014 15:26:25 +0100 Subject: [FIX] format_value: correctly compose if block, we are doing python here... bzr revid: mat@openerp.com-20140121142625-fy8zkafcvb9wwz88 --- addons/web/static/src/js/formats.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 58a785b6083..3280b9f4f75 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -191,9 +191,7 @@ instance.web.format_value = function (value, descriptor, value_if_empty) { + ' ' + normalize_format(l10n.time_format)); case 'date': if (typeof(value) == "string") - // in case value is a datetime, strip to avoid time manipulation - value = value.substring(0,10); - value = instance.web.str_to_date(value); + value = instance.web.str_to_date(value.substring(0,10)); return value.toString(normalize_format(l10n.date_format)); case 'time': if (typeof(value) == "string") -- cgit v1.2.3 From 9f3ab4599c7267b82b1d5255f31ef67b56594a68 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 21 Jan 2014 16:12:55 +0100 Subject: [FIX] FieldStatus: restore trigger get_selection on value change. Was removed rev 3738. Without this a change of record in a form view would not recompute the list of states as well as a change of state due to a button bzr revid: mat@openerp.com-20140121151255-jke0zbobb0ilpqid --- addons/web/static/src/js/view_form.js | 1 + 1 file changed, 1 insertion(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index f613d51ff97..099a094a581 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -5477,6 +5477,7 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ start: function() { this.field_manager.on("view_content_has_changed", this, this.calc_domain); this.calc_domain(); + this.on("change:value", this, this.get_selection); this.on("change:evaluated_selection_domain", this, this.get_selection); this.on("change:selection", this, function() { this.selection = this.get("selection"); -- cgit v1.2.3 From d0806ed3f7730e42aa4666c6122139121a9d7391 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 22 Jan 2014 13:44:49 +0100 Subject: [FIX] makes the querygroup methods compatible with the 'field:interval' format of groupbys accepted by read_group bzr revid: ged@openerp.com-20140122124449-4nodai5vkoz3eryf --- addons/web/static/src/js/data.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index 10ca5d74bd9..a2e3e53db3e 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -129,11 +129,14 @@ instance.web.Query = instance.web.Class.extend({ if (_.isEmpty(grouping) && !ctx['group_by_no_leaf']) { return null; } + var raw_fields = _.map(grouping.concat(this._fields || []), function (field) { + return (_.contains(field, ':')) ? field.split(':')[0] : field; + }); var self = this; return this._model.call('read_group', { groupby: grouping, - fields: _.uniq(grouping.concat(this._fields || [])), + fields: _.uniq(raw_fields), domain: this._model.domain(this._filter), context: ctx, offset: this._offset, @@ -233,12 +236,14 @@ instance.web.QueryGroup = instance.web.Class.extend({ var group_size = fixed_group[grouping_field + '_count'] || fixed_group.__count || 0; var leaf_group = fixed_group.__context.group_by.length === 0; + var raw_field = (_.contains(grouping_field, ':')) ? grouping_field.split(':')[0] : grouping_field; + this.attributes = { folded: !!(fixed_group.__fold), grouped_on: grouping_field, // if terminal group (or no group) and group_by_no_leaf => use group.__count length: group_size, - value: fixed_group[grouping_field], + value: fixed_group[raw_field], // A group is open-able if it's not a leaf in group_by_no_leaf mode has_children: !(leaf_group && fixed_group.__context['group_by_no_leaf']), -- cgit v1.2.3 From 36eedfab43a28b72a6dd6375c0f71828f238fc37 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 22 Jan 2014 14:54:26 +0100 Subject: [ADD] JSONify Date objects to a UTC datetime in OpenERP server format This way, the client can send genuine local Date objects without caring too much, the server will get them in an expected format. This can then be used by leaving Date objects in domains, and have these date objects end up correctly in the server without creators of domains having to manually serialize them to UTC from a local datetime somehow. bzr revid: xmo@openerp.com-20140122135426-zm80cj5wm9iebs76 --- addons/web/static/src/js/openerpframework.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/openerpframework.js b/addons/web/static/src/js/openerpframework.js index 22ca70ebbf7..71f45899f5f 100644 --- a/addons/web/static/src/js/openerpframework.js +++ b/addons/web/static/src/js/openerpframework.js @@ -823,13 +823,33 @@ var genericJsonRpc = function(fct_name, params, fct) { }); }; +/** + * Replacer function for JSON.stringify, serializes Date objects to UTC + * datetime in the OpenERP Server format. + * + * However, if a serialized value has a toJSON method that method is called + * *before* the replacer is invoked. Date#toJSON exists, and thus the value + * passed to the replacer is a string, the original Date has to be fetched + * on the parent object (which is provided as the replacer's context). + * + * @param {String} k + * @param {Object} v + * @returns {Object} + */ +function date_to_utc(k, v) { + var value = this[k]; + if (!(value instanceof Date)) { return v; } + + return openerp.datetime_to_str(value); +} + openerp.jsonRpc = function(url, fct_name, params, settings) { return genericJsonRpc(fct_name, params, function(data) { return $.ajax(url, _.extend({}, settings, { url: url, dataType: 'json', type: 'POST', - data: JSON.stringify(data), + data: JSON.stringify(data, date_to_utc), contentType: 'application/json' })); }); @@ -838,7 +858,7 @@ openerp.jsonRpc = function(url, fct_name, params, settings) { openerp.jsonpRpc = function(url, fct_name, params, settings) { settings = settings || {}; return genericJsonRpc(fct_name, params, function(data) { - var payload_str = JSON.stringify(data); + var payload_str = JSON.stringify(data, date_to_utc); var payload_url = $.param({r:payload_str}); var force2step = settings.force2step || false; delete settings.force2step; -- cgit v1.2.3 From 5b7ade9db180b8a038c2a9944aba85d1ffd220ea Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 22 Jan 2014 16:19:11 +0100 Subject: [ADD] ways to correctly handle local datetimes in e.g. domains * change datetime.now() to generate user-local naive datetimes * add datetime.utcnow() behaving as the old now() * add date.today() generating a user-local date (for the current day) * add datetime.replace() to replace any specific attribute of the datetime object (except tzinfo, for now) * datetime.toJSON() now returns the equivalent javascript Date object (warning: uses the datetime attributes directly, since datetimes are naive if they were created with utcnow() the Date result is going to be complete nonsense). With the previous commit datetime.now() generates a user-local now() which is converted to the correct UTC datetime when sent to the server. This means it becomes possible to generate datetime bounds for the user's local today with either datetime.datetime.now().replace(hour=0, minute=0, second=0) or datetime.datetime.combine( datetime.date.today(), datetime.time()) and once send over JSON-RPC the server will get the local datetime in UTC to the server's format. nb: user-local means "in the timezone of the user's browser" in this context. bzr revid: xmo@openerp.com-20140122151911-akn1nr6e739eg92s --- addons/web/static/src/js/pyeval.js | 49 ++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/pyeval.js b/addons/web/static/src/js/pyeval.js index 0b0e9725af9..7da0f3d6f32 100644 --- a/addons/web/static/src/js/pyeval.js +++ b/addons/web/static/src/js/pyeval.js @@ -382,13 +382,28 @@ this[key] = asJS(args[key]); } }, + replace: function () { + var args = py.PY_parseArgs(arguments, [ + ['year', py.None], ['month', py.None], ['day', py.None], + ['hour', py.None], ['minute', py.None], ['second', py.None], + ['microsecond', py.None] // FIXME: tzinfo, can't use None as valid input + ]); + var params = {}; + for(var key in args) { + if (!args.hasOwnProperty(key)) { continue; } + + var arg = args[key]; + params[key] = (arg === py.None ? this[key] : asJS(arg)); + } + return py.PY_call(datetime.datetime, params); + }, strftime: function () { var self = this; var args = py.PY_parseArgs(arguments, 'format'); return py.str.fromJSON(args.format.toJSON() .replace(/%([A-Za-z])/g, function (m, c) { switch (c) { - case 'Y': return self.year; + case 'Y': return _.str.sprintf('%04d', self.year); case 'm': return _.str.sprintf('%02d', self.month); case 'd': return _.str.sprintf('%02d', self.day); case 'H': return _.str.sprintf('%02d', self.hour); @@ -399,6 +414,17 @@ })); }, now: py.classmethod.fromJSON(function () { + var d = new Date; + return py.PY_call(datetime.datetime, [ + d.getFullYear(), d.getMonth() + 1, d.getDate(), + d.getHours(), d.getMinutes(), d.getSeconds(), + d.getMilliseconds() * 1000]); + }), + today: py.classmethod.fromJSON(function () { + var dt_class = py.PY_getAttr(datetime, 'datetime'); + return py.PY_call(py.PY_getAttr(dt_class, 'now')); + }), + utcnow: py.classmethod.fromJSON(function () { var d = new Date(); return py.PY_call(datetime.datetime, [d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate(), @@ -415,7 +441,17 @@ py.PY_getAttr(args.time, 'minute'), py.PY_getAttr(args.time, 'second') ]); - }) + }), + toJSON: function () { + return new Date( + this.year, + this.month - 1, + this.day, + this.hour, + this.minute, + this.second, + this.microsecond / 1000); + }, }); datetime.date = py.type('date', null, { __init__: function () { @@ -470,7 +506,12 @@ }, fromJSON: function (year, month, day) { return py.PY_call(datetime.date, [year, month, day]); - } + }, + today: py.classmethod.fromJSON(function () { + var d = new Date; + return py.PY_call(datetime.date, [ + d.getFullYear(), d.getMonth() + 1, d.getDate()]); + }), }); /** Returns the current local date, which means the date on the client (which can be different @@ -501,7 +542,7 @@ time.strftime = py.PY_def.fromJSON(function () { var args = py.PY_parseArgs(arguments, 'format'); var dt_class = py.PY_getAttr(datetime, 'datetime'); - var d = py.PY_call(py.PY_getAttr(dt_class, 'now')); + var d = py.PY_call(py.PY_getAttr(dt_class, 'utcnow')); return py.PY_call(py.PY_getAttr(d, 'strftime'), [args.format]); }); -- cgit v1.2.3 From a482809cf90f35b00f420e30829ed1c06769649d Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Wed, 29 Jan 2014 10:23:59 +0100 Subject: [FIX] correctly compute the attribute 'length' in a query_group so that the list view properly display groups when grouped by 'date:interval' (addon web) bzr revid: ged@openerp.com-20140129092359-20kw6n3sxqobiqu5 --- addons/web/static/src/js/data.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index a2e3e53db3e..4a0807a727a 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -234,9 +234,9 @@ instance.web.QueryGroup = instance.web.Class.extend({ this.model = new instance.web.Model( model, fixed_group.__context, fixed_group.__domain); - var group_size = fixed_group[grouping_field + '_count'] || fixed_group.__count || 0; + var raw_field = grouping_field && grouping_field.split(':')[0]; + var group_size = fixed_group[raw_field + '_count'] || fixed_group.__count || 0; var leaf_group = fixed_group.__context.group_by.length === 0; - var raw_field = (_.contains(grouping_field, ':')) ? grouping_field.split(':')[0] : grouping_field; this.attributes = { folded: !!(fixed_group.__fold), -- cgit v1.2.3 From 3a07e0a012a6914a532dfba7072c2a65e0c3627a Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 29 Jan 2014 15:14:38 +0100 Subject: [FIX] attachement: display error message (removed inexistant template) and redraw the window (to avoid getting stucked) bzr revid: mat@openerp.com-20140129141438-3883hhzdiwyoo19t --- addons/web/static/src/js/views.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 21ff627c544..1c5850d6151 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -1217,7 +1217,8 @@ instance.web.Sidebar = instance.web.Widget.extend({ this.dataset = dataset; this.model_id = model_id; if (args && args[0].error) { - this.do_warn( instance.web.qweb.render('message_error_uploading'), args[0].error); + this.do_warn(_t('Upload Error'), args[0].error); + self.redraw(); } if (!model_id) { this.on_attachments_loaded([]); -- cgit v1.2.3 From b0fa27dc7c9eda1005dd969e8d91a977fe3dbd31 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 30 Jan 2014 16:11:46 +0100 Subject: [IMP] Quick fix for cros support in webclient bzr revid: fme@openerp.com-20140130151146-twct15ruxq179ryu --- addons/web/static/src/js/openerpframework.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/openerpframework.js b/addons/web/static/src/js/openerpframework.js index 71f45899f5f..dfe7b1ebdb6 100644 --- a/addons/web/static/src/js/openerpframework.js +++ b/addons/web/static/src/js/openerpframework.js @@ -970,6 +970,7 @@ openerp.Session = openerp.Class.extend(openerp.PropertiesMixin, { this.session_id = options.session_id || null; this.override_session = options.override_session || !!options.session_id || false; this.avoid_recursion = false; + this.use_cors = options.use_cors || false; this.setup(origin); }, setup: function(origin) { @@ -1013,7 +1014,7 @@ openerp.Session = openerp.Class.extend(openerp.PropertiesMixin, { }, check_session_id: function() { var self = this; - if (this.avoid_recursion) + if (this.avoid_recursion || self.use_cors) return $.when(); if (this.session_id) return $.when(); // we already have the session id @@ -1070,6 +1071,15 @@ openerp.Session = openerp.Class.extend(openerp.PropertiesMixin, { "X-Openerp-Session-Id": self.override_session ? self.session_id || '' : '' }); } + } else if (self.use_cors) { + fct = openerp.jsonRpc; + url = self.url(url, null); + options.session_id = self.session_id || ''; + if (self.override_session) { + options.headers = _.extend({}, options.headers, { + "X-Openerp-Session-Id": self.override_session ? self.session_id || '' : '' + }); + } } else { fct = openerp.jsonpRpc; url = self.url(url, null); -- cgit v1.2.3 From 8ed584d1ac3276429bd0b108d80dcd55c89b47cd Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Thu, 30 Jan 2014 16:37:00 +0100 Subject: [FIX] simplify a computation of raw_fields to make sure it doesn't crash (_.contains expects a list, and not a string) (addon web) bzr revid: ged@openerp.com-20140130153700-2lno0uefta93ex53 --- addons/web/static/src/js/data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index 4a0807a727a..78e3001d746 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -130,7 +130,7 @@ instance.web.Query = instance.web.Class.extend({ return null; } var raw_fields = _.map(grouping.concat(this._fields || []), function (field) { - return (_.contains(field, ':')) ? field.split(':')[0] : field; + return field.split(':')[0]; }); var self = this; -- cgit v1.2.3 From 23de024718a059edd7c35292d9c76b6fa118ce22 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 31 Jan 2014 11:28:36 +0100 Subject: [IMP] attachement: remove unnecessary redraw added at rev 4128 and change message to be the same than in mail bzr revid: mat@openerp.com-20140131102836-e89xo4nrwk32uij8 --- addons/web/static/src/js/views.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 1c5850d6151..8d04110885c 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -1217,8 +1217,7 @@ instance.web.Sidebar = instance.web.Widget.extend({ this.dataset = dataset; this.model_id = model_id; if (args && args[0].error) { - this.do_warn(_t('Upload Error'), args[0].error); - self.redraw(); + this.do_warn(_t('Uploading Error'), args[0].error); } if (!model_id) { this.on_attachments_loaded([]); -- cgit v1.2.3 From ae3223907b5d33f95c2215824cce1d5a179f6f29 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 31 Jan 2014 16:26:40 +0100 Subject: [FIX] modules initialization when testing broken "adaptation" to single-instance openerp would only initialize the first set of dependencies, any further module would see its test runs without itself or its dependencies being guaranteed to be initialized/installed into the current openerp instance. bzr revid: xmo@openerp.com-20140131152640-coxqulkdb0xupbvq --- addons/web/static/src/js/testing.js | 38 +++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/testing.js b/addons/web/static/src/js/testing.js index f607b278437..c4f5aeebd60 100644 --- a/addons/web/static/src/js/testing.js +++ b/addons/web/static/src/js/testing.js @@ -15,6 +15,37 @@ openerp.testing = {}; list_editable: ['list', 'form', 'data'], }; + var initialized = []; + /** + * openerp.init is a broken-ass piece of shit, makes it impossible to + * progressively add modules, using it, retarded openerp_inited flag + * means the first tests being run get their dependencies loaded + * (basically just base and web), and for *every other module* the tests + * run without the dependencies being correctly loaded + */ + function init(modules) { + if (!initialized.length) { + openerp.init(modules); + initialized = openerp._modules.slice(); + return; + } + var to_initialize = _.difference(modules, initialized); + for (var i = 0; i < to_initialize.length; i++) { + var modname = to_initialize[i]; + var fct = openerp[modname]; + if (typeof fct === 'function') { + var module = openerp[modname] = {}; + for(var k in fct) { + if (!fct.hasOwnProperty(k)) { continue; } + module[k] = fct[k]; + } + fct(openerp, module) + } + initialized.push(modname); + openerp._modules.push(modname); + } + } + testing.dependencies = window['oe_all_dependencies'] || []; testing.current_module = null; testing.templates = { }; @@ -165,8 +196,6 @@ openerp.testing = {}; }); }; - var openerp_inited = false; - var db = window['oe_db_info']; testing.section = function (name, options, body) { if (_.isFunction(options)) { @@ -243,10 +272,7 @@ openerp.testing = {}; QUnit.test(name, function () { var instance = openerp; - if (!openerp_inited) { - openerp.init(module_deps); - openerp_inited = true; - } + init(module_deps); instance.session = new instance.web.Session(); instance.session.uid = 42; if (_.isNumber(opts.asserts)) { -- cgit v1.2.3 From df0076c67d5ea2f7a6d4ba6aa5b104700476c69b Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Tue, 4 Feb 2014 16:05:44 +0100 Subject: [FIX] getParent() js error when clicking to fast on menu items of dashboards bzr revid: cto@openerp.com-20140204150544-nkuhxree6qijihq2 --- addons/web/static/src/js/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 557d0baa124..3d7ba5ae293 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -407,7 +407,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea context: this.dataset.get_context(), }); - $.when(load_view).then(function (r) { + this.alive($.when(load_view)).then(function (r) { return self.search_view_loaded(r) }).fail(function () { self.ready.reject.apply(null, arguments); -- cgit v1.2.3 From 42952bb7cf514b43eac598397e7bfad4cd943bc7 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Wed, 5 Feb 2014 10:17:49 +0100 Subject: [REM] Remove LoginForm javascript bzr revid: fme@openerp.com-20140205091749-39333kr3hz0dt4wg --- addons/web/static/src/js/chrome.js | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index afa761d7025..377c5755ce9 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -513,7 +513,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ var fields = $(form).serializeArray(); self.rpc("/web/database/create", {'fields': fields}).done(function(result) { if (result) { - instance.web.redirect('/web') + instance.web.redirect('/web'); } else { alert("Failed to create database"); } @@ -1483,24 +1483,6 @@ instance.web.embed = function (origin, dbname, login, key, action, options) { client.insertAfter(currentScript); }; -openerp.web.LoginForm = openerp.web.Widget.extend({ - init: function ($form) { - this._super(/* no parent */); - this.setElement($form); - this.$el.on('submit', this.on_submit); - this.start(); - }, - start: function () { - if (location.hash) { - this.$el.attr('action', this.$el.attr('action') + location.hash); - } - return this._super(); - }, - on_submit: function () { - return true; - }, -}); - })(); // vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: -- cgit v1.2.3 From b75c52f3edad2f296b38e6e32b53e8730bad4ae8 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 6 Feb 2014 11:24:09 +0100 Subject: [IMP] reference fields: display a more user-friendly window title when open a chosen many2one record in reference field bzr revid: mat@openerp.com-20140206102409-4lbx7ofsgz8speni --- addons/web/static/src/js/view_form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index a1813621977..feee1d8da4d 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -4920,7 +4920,7 @@ instance.web.form.FieldReference = instance.web.form.AbstractField.extend(instan .on('blurred', null, function () {self.trigger('blurred')}); this.m2o = new instance.web.form.FieldMany2One(fm, { attrs: { - name: 'm2o', + name: 'Referenced Document', modifiers: JSON.stringify({readonly: this.get('effective_readonly')}), }}); this.m2o.on("change:value", this, this.data_changed); -- cgit v1.2.3 From 0821af1af96c0ff59770a32c03b0bd5cdf960c39 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 10 Feb 2014 13:34:16 +0100 Subject: [FIX] close autocomplete listing on input Closing previously occured on search request (so that a user wouldn't be able to select "old" data on new search request), but ``search`` is only triggered after the search delay. Worked when delay was 0, with it being moved to 250 a user can get results matching the previous search instead of the current one. Trigger a closing of the current results list on any ``input`` event, which is when text is entered in any of the searchview's ``InputView``. bzr revid: xmo@openerp.com-20140210123416-cfc0x24bfkiv4lse --- addons/web/static/src/js/search.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index fa9bae9969d..903a9f4683e 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -473,12 +473,9 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea * Sets up search view's view-wide auto-completion widget */ setup_global_completion: function () { - var self = this; - var autocomplete = this.$el.autocomplete({ source: this.proxy('complete_global_search'), select: this.proxy('select_completion'), - search: function () { self.$el.autocomplete('close'); }, focus: function (e) { e.preventDefault(); }, html: true, autoFocus: true, @@ -486,6 +483,10 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea delay: 250, }).data('autocomplete'); + this.$el.on('input', function () { + this.$el.autocomplete('close'); + }.bind(this)); + // MonkeyPatch autocomplete instance _.extend(autocomplete, { _renderItem: function (ul, item) { -- cgit v1.2.3 From 749e05ccb81b3a0cd442c6211c82e5fc7c067127 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Mon, 10 Feb 2014 15:00:32 +0100 Subject: [FIX] close autocomplete listing on input Closing previously occured on search request (so that a user wouldn't be able to select "old" data on new search request), but ``search`` is only triggered after the search delay. Worked when delay was 0, with it being moved to 250 a user can get results matching the previous search instead of the current one. Trigger a closing of the current results list on any ``input`` event, which is when text is entered in any of the searchview's ``InputView`` bzr revid: dle@openerp.com-20140210140032-06dnlxepcc5ae21f --- addons/web/static/src/js/search.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 3d7ba5ae293..ad212d7f86d 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -466,12 +466,9 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea * Sets up search view's view-wide auto-completion widget */ setup_global_completion: function () { - var self = this; - var autocomplete = this.$el.autocomplete({ source: this.proxy('complete_global_search'), select: this.proxy('select_completion'), - search: function () { self.$el.autocomplete('close'); }, focus: function (e) { e.preventDefault(); }, html: true, autoFocus: true, @@ -479,6 +476,10 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea delay: 250, }).data('autocomplete'); + this.$el.on('input', function () { + this.$el.autocomplete('close'); + }.bind(this)); + // MonkeyPatch autocomplete instance _.extend(autocomplete, { _renderItem: function (ul, item) { -- cgit v1.2.3 From 2223ba5600875eb1d92ec1c70feacd60ebe6a96b Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 12 Feb 2014 15:13:46 +0100 Subject: [FIX] search view: slightly more readable error when search filters fail to evaluate Prints the error details instead of: Uncaught TypeError: Cannot read property 'length' of undefined' addons/web/static/src/js/views.js bzr revid: odo@openerp.com-20140212141346-hpw05sv3ctr243db --- addons/web/static/src/js/views.js | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 82a2095bace..eed98f9fc31 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -815,6 +815,11 @@ instance.web.ViewManager = instance.web.Widget.extend({ contexts: [action_context].concat(contexts || []), group_by_seq: groupbys || [] }).done(function (results) { + if (results.error) { + throw new Error( + _.str.sprintf(_t("Failed to evaluate search criterions")+": \n%s", + JSON.stringify(results.error))); + } self.dataset._model = new instance.web.Model( self.dataset.model, results.context, results.domain); var groupby = results.group_by.length -- cgit v1.2.3 From 409c3cfe9f1cdda1b8d9672fc3c0c246ed425894 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 13 Feb 2014 09:50:08 +0100 Subject: [FIX] data: _.find (prefered to older _.detect) may return undefined if no match and would trow an error when applying .values Instead returns undefined which is handled below. This does not solve the issue when records are not loaded properly but gives a better information on the reason. bzr revid: mat@openerp.com-20140213085008-pnq4r0ebfl072u78 --- addons/web/static/src/js/data.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index e1290deac02..abfb4c15347 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -848,7 +848,8 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({ }); var return_records = function() { var records = _.map(ids, function(id) { - return _.extend({}, _.detect(self.cache, function(c) {return c.id === id;}).values, {"id": id}); + var c = _.find(self.cache, function(c) {return c.id === id;}); + return _.isUndefined(c) ? c : _.extend({}, c.values, {"id": id}); }); if (self.debug_mode) { if (_.include(records, undefined)) { -- cgit v1.2.3 From a8943b416a892c4da76aa0887886622e525db8b8 Mon Sep 17 00:00:00 2001 From: "Mohammed Shekha (OpenERP)" Date: Thu, 13 Feb 2014 17:25:56 +0530 Subject: [FIX]Web, Statusbar: Fixed the issue of statubar in chrome is aligned, it is aligned in inline block. bzr revid: msh@openerp.com-20140213115556-irdodahpw0atgy5u --- addons/web/static/src/js/view_form.js | 3 --- 1 file changed, 3 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index feee1d8da4d..c996a57ded7 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -5389,9 +5389,6 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ if (this.options.clickable) { this.$el.on('click','li',this.on_click_stage); } - if (this.$el.parent().is('header')) { - this.$el.after('
'); - } this._super(); }, set_value: function(value_) { -- cgit v1.2.3 From 8877c10161fc66e2b16b2ae81beaf34749b32396 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 14 Feb 2014 12:15:40 +0100 Subject: [FIX] login: look at the value of action_id on the current res.users to execute the action instead of the first link (Inbox). Bring back 6.1 behaviour. bzr revid: mat@openerp.com-20140214111540-sbn3y6ou3vrjza15 --- addons/web/static/src/js/chrome.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index b51f86ba195..3e42a697c19 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1407,12 +1407,18 @@ instance.web.WebClient = instance.web.Client.extend({ $(window).bind('hashchange', this.on_hashchange); var state = $.bbq.getState(true); + if (_.isEmpty(state) || state.action == "login") { self.menu.has_been_loaded.done(function() { - var first_menu_id = self.menu.$el.find("a:first").data("menu"); - if(first_menu_id) { - self.menu.menu_click(first_menu_id); - } + new instance.web.Model("res.users").call("read", [self.session.uid, ["action_id"]]).done(function(data) { + if(data.action_id) { + self.action_manager.do_action(data.action_id[0]); + } else { + var first_menu_id = self.menu.$el.find("a:first").data("menu"); + if(first_menu_id) + self.menu.menu_click(first_menu_id); + } + }); }); } else { $(window).trigger('hashchange'); -- cgit v1.2.3 From d65df64cddcfe2cfd9bb23ab2aca3b85a35aa1d3 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 14 Feb 2014 12:17:07 +0100 Subject: [IMP] always click on first link to have menus and breadcrumb bzr revid: mat@openerp.com-20140214111707-7zzpeccs9aanfdct --- addons/web/static/src/js/chrome.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 3e42a697c19..fed67a8af1f 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1411,12 +1411,12 @@ instance.web.WebClient = instance.web.Client.extend({ if (_.isEmpty(state) || state.action == "login") { self.menu.has_been_loaded.done(function() { new instance.web.Model("res.users").call("read", [self.session.uid, ["action_id"]]).done(function(data) { + var first_menu_id = self.menu.$el.find("a:first").data("menu"); + if(first_menu_id) + self.menu.menu_click(first_menu_id); + if(data.action_id) { self.action_manager.do_action(data.action_id[0]); - } else { - var first_menu_id = self.menu.$el.find("a:first").data("menu"); - if(first_menu_id) - self.menu.menu_click(first_menu_id); } }); }); -- cgit v1.2.3 From 5ef7c4a6a1838a3821ee1bcf14d93d0203e9fbc1 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Mon, 17 Feb 2014 11:49:20 +0100 Subject: [FIX] getParent() js error when clicking to fast on menu items that load a list view after loading a form view bzr revid: cto@openerp.com-20140217104920-fu8hcqd51bh7qnrp --- addons/web/static/src/js/view_list.js | 7 +++++-- addons/web/static/src/js/views.js | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index f3ecc373ca5..5bee82c28d2 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -1623,9 +1623,12 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we function synchronized(fn) { var fn_mutex = new $.Mutex(); return function () { + var obj = this; var args = _.toArray(arguments); - args.unshift(this); - return fn_mutex.exec(fn.bind.apply(fn, args)); + return fn_mutex.exec(function () { + if (obj.isDestroyed()) { return $.when(); } + return fn.apply(obj, args) + }); }; } var DataGroup = instance.web.Class.extend({ diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 8d04110885c..875b113a82f 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -1301,7 +1301,7 @@ instance.web.View = instance.web.Widget.extend({ "context": this.dataset.get_context(), }); } - return view_loaded_def.then(function(r) { + return this.alive(view_loaded_def).then(function(r) { self.fields_view = r; // add css classes that reflect the (absence of) access rights self.$el.addClass('oe_view') -- cgit v1.2.3 From e4579fdbbd0380f04f179f230f0001ad531346a1 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 17 Feb 2014 23:46:26 +0100 Subject: [IMP] actionmanager report port to the new synchronous pyeval api. bzr revid: al@openerp.com-20140217224626-3s0q34x0jw8t4okg --- addons/web/static/src/js/views.js | 67 ++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 36 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 82a2095bace..79a75551c8d 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -496,44 +496,39 @@ instance.web.ActionManager = instance.web.Widget.extend({ ir_actions_report_xml: function(action, options) { var self = this; instance.web.blockUI(); - return instance.web.pyeval.eval_domains_and_contexts({ - contexts: [action.context], - domains: [] - }).then(function(res) { - action = _.clone(action); - action.context = res.context; + action = _.clone(action); + var eval_contexts = ([instance.session.user_context] || []).concat([action.context]); + action.context = instance.web.pyeval.eval('contexts',eval_contexts); - // iOS devices doesn't allow iframe use the way we do it, - // opening a new window seems the best way to workaround - if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) { - var params = { - action: JSON.stringify(action), - token: new Date().getTime() - }; - var url = self.session.url('/web/report', params); - instance.web.unblockUI(); - $('')[0].click(); - return; - } - - var c = instance.webclient.crashmanager; - return $.Deferred(function (d) { - self.session.get_file({ - url: '/web/report', - data: {action: JSON.stringify(action)}, - complete: instance.web.unblockUI, - success: function(){ - if (!self.dialog) { - options.on_close(); - } - self.dialog_stop(); - d.resolve(); - }, - error: function () { - c.rpc_error.apply(c, arguments); - d.reject(); + // iOS devices doesn't allow iframe use the way we do it, + // opening a new window seems the best way to workaround + if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) { + var params = { + action: JSON.stringify(action), + token: new Date().getTime() + }; + var url = self.session.url('/web/report', params); + instance.web.unblockUI(); + $('')[0].click(); + return; + } + var c = instance.webclient.crashmanager; + return $.Deferred(function (d) { + self.session.get_file({ + url: '/web/report', + data: {action: JSON.stringify(action)}, + complete: instance.web.unblockUI, + success: function(){ + if (!self.dialog) { + options.on_close(); } - }); + self.dialog_stop(); + d.resolve(); + }, + error: function () { + c.rpc_error.apply(c, arguments); + d.reject(); + } }); }); }, -- cgit v1.2.3 From 2e831ab7c377408782ab96c303f6fa50884d76e4 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 18 Feb 2014 11:14:38 +0100 Subject: [IMP] data: skip read_ids call when got no id (opw 604099). This avoids making useless calls to to read the values of o2m fields when the read on a record already told us there was no ids. bzr revid: mat@openerp.com-20140218101438-yqim33cvtg6wt4mw --- addons/web/static/src/js/data.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index abfb4c15347..04b02294463 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -428,6 +428,9 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin, * @returns {$.Deferred} */ read_ids: function (ids, fields, options) { + if (_.isEmpty(ids)) + return $.Deferred().resolve([]); + options = options || {}; // TODO: reorder results to match ids list return this._model.call('read', -- cgit v1.2.3 From c7b4f44b22f4d9ad91c7ea2547e0757dc70bf3b0 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Tue, 18 Feb 2014 17:21:25 +0100 Subject: [FIX] web: fix handling of manyone with selection widget Following the remove of widget selection handling in ir_ui_view of revision 4854.4.298 revid:al@openerp.com-20140121112759-zavwqdyv8kdq4oys bzr revid: dle@openerp.com-20140218162125-bwse328ybq9d6c2v --- addons/web/static/src/js/formats.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 2f6bbcebc4f..3c32dbe0426 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -205,7 +205,7 @@ instance.web.format_value = function (value, descriptor, value_if_empty) { case 'selection': case 'statusbar': // Each choice is [value, label] if(_.isArray(value)) { - value = value[0]; + return value[1]; } var result = _(descriptor.selection).detect(function (choice) { return choice[0] === value; -- cgit v1.2.3 From 50849309d17db9a3d5fd0bcd9d546843aee7d3ea Mon Sep 17 00:00:00 2001 From: "jke@openerp.com" <> Date: Wed, 19 Feb 2014 17:31:34 +0100 Subject: [FIX] web_calendar: correct timezone handling when creating new events bzr revid: odo@openerp.com-20140219163134-dzmx34yffnithn30 --- addons/web/static/src/js/views.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index cb0d130e305..689b4d947fb 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -600,6 +600,7 @@ instance.web.ViewManager = instance.web.Widget.extend({ action_views_ids : views_ids }, self.flags, self.flags[view.view_type] || {}, view.options || {}) }); + views_ids[view.view_type] = view.view_id; }); if (this.flags.views_switcher === false) { @@ -607,7 +608,11 @@ instance.web.ViewManager = instance.web.Widget.extend({ } // If no default view defined, switch to the first one in sequence var default_view = this.flags.default_view || this.views_src[0].view_type; - return this.switch_mode(default_view); + + + return this.switch_mode(default_view, null, this.flags[default_view] && this.flags[default_view].options); + + }, switch_mode: function(view_type, no_store, view_options) { var self = this; -- cgit v1.2.3 From bb89e548668b88a231a364d106a2cd6e57442ae6 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 19 Feb 2014 17:32:37 +0100 Subject: [FIX] web: set default: handle false values + correct display of selection fields bzr revid: odo@openerp.com-20140219163237-ns5zbzxvtrr3a6ed --- addons/web/static/src/js/view_form.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 0a30d4db649..599664d14de 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -1030,8 +1030,9 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM open_defaults_dialog: function () { var self = this; var display = function (field, value) { + if (!value) { return value; } if (field instanceof instance.web.form.FieldSelection) { - return _(field.values).find(function (option) { + return _(field.get('values')).find(function (option) { return option[0] === value; })[1]; } else if (field instanceof instance.web.form.FieldMany2One) { -- cgit v1.2.3 From 16a5c4511469c12764d0896fc0f2a774d0fc1c5a Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Sat, 22 Feb 2014 03:57:06 +1100 Subject: [FIX] home action: open the linked menu in addition to execute the action. The menu tree is now correctly displayed instead of only messaging. bzr revid: mat@openerp.com-20140221165706-79uqffr5nk4zbj5e --- addons/web/static/src/js/chrome.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index af271e3f2f9..8fb13aae746 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1410,12 +1410,13 @@ instance.web.WebClient = instance.web.Client.extend({ if (_.isEmpty(state) || state.action == "login") { self.menu.has_been_loaded.done(function() { new instance.web.Model("res.users").call("read", [self.session.uid, ["action_id"]]).done(function(data) { - var first_menu_id = self.menu.$el.find("a:first").data("menu"); - if(first_menu_id) - self.menu.menu_click(first_menu_id); - if(data.action_id) { self.action_manager.do_action(data.action_id[0]); + self.menu.open_action(data.action_id[0]); + } else { + var first_menu_id = self.menu.$el.find("a:first").data("menu"); + if(first_menu_id) + self.menu.menu_click(first_menu_id); } }); }); -- cgit v1.2.3 From f29f1e6f049428e205dcadcb613857822e24c990 Mon Sep 17 00:00:00 2001 From: "Mohammed Shekha (OpenERP)" Date: Tue, 4 Mar 2014 16:36:59 +0530 Subject: [FIX]Fixed the issue of o2m sorting by column, m2o field does not give proper result for sorting because whole value of m2o [id, value] going to compare for sorting. bzr revid: msh@openerp.com-20140304110659-4uu38feetsjj0tt5 --- addons/web/static/src/js/data.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index abfb4c15347..e7dc81ef787 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -877,6 +877,10 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({ sign = -1; field = field.slice(1); } + //m2o should be searched based on value[1] not based whole value(i.e. [id, value]) + if(_.isArray(a[field]) && a[field].length == 2 && _.isString(a[field][1])){ + return sign * compare(a[field][1], b[field][1]); + } return sign * compare(a[field], b[field]); }, 0); }); -- cgit v1.2.3 From 618c8b910077981757967966d0221af7690d10a4 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 7 Mar 2014 15:12:57 +0100 Subject: [FIX] quick create: do not add the id in the form if the form is readonly (eg: clicking on save button will make the form uneditable) bzr revid: mat@openerp.com-20140307141257-rvusvzm6oq3tel51 --- addons/web/static/src/js/view_form.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index c996a57ded7..706bee5bd1a 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -2977,7 +2977,8 @@ instance.web.form.CompletionFieldMixin = { if (self.options.quick_create === undefined || self.options.quick_create) { new instance.web.DataSet(this, this.field.relation, self.build_context()) .name_create(name).done(function(data) { - self.add_id(data[0]); + if (!self.get('effective_readonly')) + self.add_id(data[0]); }).fail(function(error, event) { event.preventDefault(); slow_create(); -- cgit v1.2.3 From c033e5a5351a070043131720faf8f8f7df669571 Mon Sep 17 00:00:00 2001 From: Xavier ALT <> Date: Tue, 11 Mar 2014 10:15:22 +0100 Subject: [FIX] web: on SearchPopup creation concat build context even if we have initial_ids On SearchPopupCreation, if we have initial_ids - 1st search_read() will be missing custom context defined on the field. 1. defined view like this: 2. in we expand the list of available item, name_search() has 'test' in context 3. in we click on 'Search More', search_read() is missing 'test' in context 4. if we change filter add/remove item, search_read() will have 'test' in context Step 3. is wrong, should also have 'test' in context lp bug: https://launchpad.net/bugs/1209295 fixed bzr revid: mat@openerp.com-20140311091522-03imwd5rj3rmwapl --- addons/web/static/src/js/view_form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 706bee5bd1a..edb44e7ea06 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -4796,7 +4796,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend this.searchview.on('search_data', self, function(domains, contexts, groupbys) { if (self.initial_ids) { self.do_search(domains.concat([[["id", "in", self.initial_ids]], self.domain]), - contexts, groupbys); + contexts.concat(self.context), groupbys); self.initial_ids = undefined; } else { self.do_search(domains.concat([self.domain]), contexts.concat(self.context), groupbys); -- cgit v1.2.3 From 6e9f3ad8064bcd8491e85817d704aba6eb0d944c Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Tue, 11 Mar 2014 11:49:47 +0100 Subject: [FIX] web: set z-index of 9999 for autocompletion pane of search bar, to avoid being behind jquery ui dialogs. Besides, this pane should always be on top, therefore we can assume that setting 9999 will not have bad side effects bzr revid: dle@openerp.com-20140311104947-is5qpw71y1m2oakf --- addons/web/static/src/js/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index ad212d7f86d..b82ad6504a9 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -341,7 +341,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea } }, 'autocompleteopen': function () { - this.$el.autocomplete('widget').css('z-index', 1004); + this.$el.autocomplete('widget').css('z-index', 9999); }, }, /** -- cgit v1.2.3 From 71d8f8f1c4631c7dcbe3d9db449c16c611649e16 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 13 Mar 2014 13:38:11 +0100 Subject: [FIX] pager: show the pagger earlier to avoid slow loading to mix list and form pagers when fast switching bzr revid: mat@openerp.com-20140313123811-ej7lu53xp51kn6gu --- addons/web/static/src/js/view_form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index edb44e7ea06..f1b30f6b8e1 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -276,6 +276,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM filter: 'alpha(opacity = 0)' }); this.$el.add(this.$buttons).removeClass('oe_form_dirty'); + this.$pager.toggle(this.dataset.ids.length > 1); var shown = this.has_been_loaded; if (options.reload !== false) { @@ -420,7 +421,6 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM this.do_update_pager(); }, do_update_pager: function(hide_index) { - this.$pager.toggle(this.dataset.ids.length > 1); if (hide_index) { $(".oe_form_pager_state", this.$pager).html(""); } else { -- cgit v1.2.3 From 08e07af590759fd08118e70edf4d8004690e755e Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 14 Mar 2014 12:27:09 +0100 Subject: [FIX] pager: do not try to toggle the visibility if the pager do not exists yet bzr revid: mat@openerp.com-20140314112709-0sqq6tcpmza34q1e --- addons/web/static/src/js/view_form.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index f1b30f6b8e1..cd220ca9ece 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -271,12 +271,14 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM if (this.$buttons) { this.$buttons.show(); } + if (this.$pager) { + this.$pager.toggle(this.dataset.ids.length > 1); + } this.$el.show().css({ opacity: '0', filter: 'alpha(opacity = 0)' }); this.$el.add(this.$buttons).removeClass('oe_form_dirty'); - this.$pager.toggle(this.dataset.ids.length > 1); var shown = this.has_been_loaded; if (options.reload !== false) { -- cgit v1.2.3 From 53922c95930716b69b60170acceea60dab5cc9de Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 14 Mar 2014 14:28:54 +0100 Subject: [FIX] pager: revert of revision 4159, the pager was disapearing when going in editable mode (which is more problematic that the issue rev 4159 was trying to fix) bzr revid: mat@openerp.com-20140314132854-8ie8sosx9xecuww4 --- addons/web/static/src/js/view_form.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index cd220ca9ece..edb44e7ea06 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -271,9 +271,6 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM if (this.$buttons) { this.$buttons.show(); } - if (this.$pager) { - this.$pager.toggle(this.dataset.ids.length > 1); - } this.$el.show().css({ opacity: '0', filter: 'alpha(opacity = 0)' @@ -423,6 +420,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM this.do_update_pager(); }, do_update_pager: function(hide_index) { + this.$pager.toggle(this.dataset.ids.length > 1); if (hide_index) { $(".oe_form_pager_state", this.$pager).html(""); } else { -- cgit v1.2.3 From 2a4d8bc6d5e1e0efa382beb3381460f49d201dec Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 20 Feb 2014 15:13:02 +0100 Subject: [ADD] web: add no_create option in view_form, allowing to remove create and edit (and quick create) Before, we used to use selection widget to hide or disable the create and edit of many2one fields, but this is actually an abuse of the selection widget, this is not its purpose bzr revid: dle@openerp.com-20140220141302-3paib80ixiyi66qg --- addons/web/static/src/js/view_form.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 599664d14de..f1fc377fa94 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -3092,7 +3092,7 @@ instance.web.form.CompletionFieldMixin = { // quick create var raw_result = _(data.result).map(function(x) {return x[1];}); if (search_val.length > 0 && !_.include(raw_result, search_val) && - ! (self.options && self.options.no_quick_create)) { + ! (self.options && (self.options.no_create || self.options.no_quick_create))) { values.push({ label: _.str.sprintf(_t('Create "%s"'), $('').text(search_val).html()), @@ -3103,13 +3103,15 @@ instance.web.form.CompletionFieldMixin = { }); } // create... - values.push({ - label: _t("Create and Edit..."), - action: function() { - self._search_create_popup("form", undefined, self._create_context(search_val)); - }, - classname: 'oe_m2o_dropdown_option' - }); + if (!(self.options && self.options.no_create)){ + values.push({ + label: _t("Create and Edit..."), + action: function() { + self._search_create_popup("form", undefined, self._create_context(search_val)); + }, + classname: 'oe_m2o_dropdown_option' + }); + } return values; }); -- cgit v1.2.3 From b79f35471ecd27f1372849a9fd63cac7f740d2fd Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 21 Feb 2014 10:55:00 +0100 Subject: [FIX] testing: rpc tests works directly on the source database instead of copying it bzr revid: chs@openerp.com-20140221095500-5cer5exzdei76y1d --- addons/web/static/src/js/testing.js | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/testing.js b/addons/web/static/src/js/testing.js index c4f5aeebd60..41dd2f03ad9 100644 --- a/addons/web/static/src/js/testing.js +++ b/addons/web/static/src/js/testing.js @@ -305,39 +305,16 @@ openerp.testing = {}; case 'rpc': async = true; (function () { - // Bunch of random base36 characters - var dbname = 'test_' + Math.random().toString(36).slice(2); - // Add db setup/teardown at the start of the stack + // Add a session setup at the start of the stack to ensure user is logged in case_stack = case_stack.unshift(function (instance) { // FIXME hack: don't want the session to go through shitty loading process of everything instance.session.session_init = testing.noop; instance.session.load_modules = testing.noop; instance.session.session_bind(); - return instance.session.rpc('/web/database/duplicate', { - fields: [ - {name: 'super_admin_pwd', value: db.supadmin}, - {name: 'db_original_name', value: db.source}, - {name: 'db_name', value: dbname} - ] - }).then(function (result) { - if (result.error) { - return $.Deferred().reject(result.error).promise(); - } - return instance.session.session_authenticate( - dbname, 'admin', db.password, true); - }); - }, function (instance) { - return instance.session.rpc('/web/database/drop', { - fields: [ - {name: 'drop_pwd', value: db.supadmin}, - {name: 'drop_db', value: dbname} - ] - }).then(function (result) { - if (result.error) { - return $.Deferred().reject(result.error).promise(); - } - return result; - }); + if (instance.session.session_is_valid()) { + return $.when(); + } + return instance.session.session_authenticate(db.source, 'admin', db.password, true); }); })(); } -- cgit v1.2.3 From bb7eb5269917cfde51abb50a4dca175ddd371fb9 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 21 Feb 2014 15:35:18 +0100 Subject: [REM] RPC from js/qunit tests They're a pain in the ass, they never worked right and they're basically useless. Screw it. bzr revid: xmo@openerp.com-20140221143518-hv3rjkw2b00ughvh --- addons/web/static/src/js/testing.js | 50 ------------------------------------- 1 file changed, 50 deletions(-) (limited to 'addons/web/static/src/js') diff --git a/addons/web/static/src/js/testing.js b/addons/web/static/src/js/testing.js index 41dd2f03ad9..1f1c718ad5f 100644 --- a/addons/web/static/src/js/testing.js +++ b/addons/web/static/src/js/testing.js @@ -196,7 +196,6 @@ openerp.testing = {}; }); }; - var db = window['oe_db_info']; testing.section = function (name, options, body) { if (_.isFunction(options)) { body = options; @@ -235,40 +234,6 @@ openerp.testing = {}; .push(env._oe.setup, env._oe.teardown) .push(options.setup, options.teardown); var opts = _.defaults({}, options, env._oe); - // FIXME: if this test is ignored, will still query - if (opts.rpc === 'rpc' && !db) { - QUnit.config.autostart = false; - db = { - source: null, - supadmin: null, - password: null - }; - var $msg = $('
') - .append('

A test needs to clone a database

') - .append('

Please provide the source clone information

') - .append(' Source DB: ').append('').append('
') - .append(' DB Password: ').append('').append('
') - .append('Admin Password: ').append('').append('
') - .append('') - .submit(function (e) { - e.preventDefault(); - e.stopPropagation(); - db.source = $msg.find('input[name=source]').val(); - db.supadmin = $msg.find('input[name=supadmin]').val(); - db.password = $msg.find('input[name=password]').val(); - QUnit.start(); - $.unblockUI(); - }); - $.blockUI({ - message: $msg, - css: { - fontFamily: 'monospace', - textAlign: 'left', - whiteSpace: 'pre-wrap', - cursor: 'default' - } - }); - } QUnit.test(name, function () { var instance = openerp; @@ -302,21 +267,6 @@ openerp.testing = {}; instance.session.responses[spec] = handler; }; break; - case 'rpc': - async = true; - (function () { - // Add a session setup at the start of the stack to ensure user is logged in - case_stack = case_stack.unshift(function (instance) { - // FIXME hack: don't want the session to go through shitty loading process of everything - instance.session.session_init = testing.noop; - instance.session.load_modules = testing.noop; - instance.session.session_bind(); - if (instance.session.session_is_valid()) { - return $.when(); - } - return instance.session.session_authenticate(db.source, 'admin', db.password, true); - }); - })(); } // Always execute tests asynchronously -- cgit v1.2.3