diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 1955298ba27..1742bd91c95 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -487,6 +487,15 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{ this.selected_password = localStorage.getItem('last_password_login_success'); } } + + var qs = jQuery.deparam(jQuery.param.querystring()); + if (qs.db) { + this.selected_db = qs.db; + } + if (qs.login) { + this.selected_login = qs.login; + } + }, start: function() { var self = this; @@ -823,7 +832,9 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{ this.session.active_id = id; this.rpc('/web/menu/action', {'menu_id': id}, this.on_menu_action_loaded); } - ev.stopPropagation(); + if (ev) { + ev.stopPropagation(); + } return false; }, do_menu_click: function($clicked_menu, manual) { @@ -866,6 +877,7 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{ $sub_menu.hide(); return true; } + return manual; } else { return true; } diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index b1708bb5826..c3ff924c8e9 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -74,7 +74,6 @@ openerp.web.qweb.debug = (window.location.search.indexOf('?debug') !== -1); } return this; } - // This should NOT be used, like callbackenable it's too hackish not enough javasish Class.include = function (properties) { for (var name in properties) { if (typeof properties[name] !== 'function' @@ -288,14 +287,12 @@ openerp.web.Registry = openerp.web.Class.extend( /** @lends openerp.web.Registry */ get_any: function (keys) { for (var i=0; i 1 && _.trim(splitted[0]) === "parent" && self.dataset.parent_view) { - if (parent_fields === null) { - parent_fields = self.dataset.parent_view.get_fields_values(); - } - var p_val = parent_fields[_.trim(splitted[1])]; - if (p_val !== undefined) { - args.push(p_val == null ? false : p_val); - return; + var self = this; + var act = function() { + try { + processed = processed || []; + if (widget.node.attrs.on_change) { + var onchange = _.trim(widget.node.attrs.on_change); + var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/); + if (call) { + var method = call[1], args = []; + var context_index = null; + var argument_replacement = { + 'False' : function() {return false;}, + 'True' : function() {return true;}, + 'None' : function() {return null;}, + 'context': function(i) { + context_index = i; + var ctx = widget.build_context ? widget.build_context() : {}; + return ctx; + } + }; + var parent_fields = null; + _.each(call[2].split(','), function(a, i) { + var field = _.trim(a); + if (field in argument_replacement) { + args.push(argument_replacement[field](i)); + return; + } else if (self.fields[field]) { + var value = self.fields[field].get_on_change_value(); + args.push(value == null ? false : value); + return; + } else { + var splitted = field.split('.'); + if (splitted.length > 1 && _.trim(splitted[0]) === "parent" && self.dataset.parent_view) { + if (parent_fields === null) { + parent_fields = self.dataset.parent_view.get_fields_values(); + } + var p_val = parent_fields[_.trim(splitted[1])]; + if (p_val !== undefined) { + args.push(p_val == null ? false : p_val); + return; + } } } - } - throw "Could not get field with name '" + field + - "' for onchange '" + onchange + "'"; - }); - var ajax = { - url: '/web/dataset/call', - async: false - }; - return this.rpc(ajax, { - model: this.dataset.model, - method: method, - args: [(this.datarecord.id == null ? [] : [this.datarecord.id])].concat(args), - context_id: context_index === null ? null : context_index + 1 - }, function(response) { - self.on_processed_onchange(response, processed); - }); - } else { - console.log("Wrong on_change format", on_change); + throw "Could not get field with name '" + field + + "' for onchange '" + onchange + "'"; + }); + var ajax = { + url: '/web/dataset/call', + async: false + }; + return self.rpc(ajax, { + model: self.dataset.model, + method: method, + args: [(self.datarecord.id == null ? [] : [self.datarecord.id])].concat(args), + context_id: context_index === null ? null : context_index + 1 + }).pipe(function(response) { + return self.on_processed_onchange(response, processed); + }); + } else { + console.log("Wrong on_change format", on_change); + } } - } + } catch(e) { + console.error(e); + return $.Deferred().reject(); + } + }; + this.on_change_lock = this.on_change_lock.pipe(act, act); + return this.on_change_lock; }, on_processed_onchange: function(response, processed) { + try { var result = response; if (result.value) { for (var f in result.value) { @@ -319,7 +331,11 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# if (result.domain) { // TODO: } - this.ready = true; + return $.Deferred().resolve(); + } catch(e) { + console.error(e); + return $.Deferred().reject(); + } }, on_button_new: function() { var self = this; @@ -367,9 +383,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# do_save: function(success, prepend_on_create) { var self = this; var action = function() { - if (!self.ready) { - return $.Deferred().reject(); - } + try { + if (!self.initial_mutating_lock.isResolved() && !self.initial_mutating_lock.isRejected()) + return; var form_dirty = false, form_invalid = false, values = {}, @@ -403,8 +419,13 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# }).then(success); } } + } catch (e) { + console.error(e); + return $.Deferred().reject(); + } }; - this.save_lock = this.save_lock.pipe(action, action); + this.mutating_lock = this.mutating_lock.pipe(action, action); + return this.mutating_lock; }, do_save_edit: function() { this.do_save(); @@ -429,7 +450,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# // should not happen in the server, but may happen for internal purpose return $.Deferred().reject(); } else { - return this.reload().then(success); + this.reload(); + return $.when().then(success); } }, /** @@ -463,9 +485,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# this.sidebar.attachments.do_update(); } console.debug("The record has been created with id #" + this.datarecord.id); - return this.reload().pipe(function() { - return _.extend(r, {created: true}); - }).then(success); + this.reload() + return $.when(_.extend(r, {created: true})).then(success); } }, on_action: function (action) { @@ -475,11 +496,16 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# console.debug("Cancelling form"); }, reload: function() { - if (this.dataset.index == null || this.dataset.index < 0) { - return $.when(this.on_button_new()); - } else { - return this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded); - } + var self = this; + var act = function() { + if (self.dataset.index == null || self.dataset.index < 0) { + return $.when(self.on_button_new()); + } else { + return self.dataset.read_index(_.keys(self.fields_view.fields), self.on_record_loaded); + } + }; + this.reload_lock = this.reload_lock.pipe(act, act); + return this.reload_lock; }, get_fields_values: function() { var values = {}; @@ -545,8 +571,12 @@ openerp.web.FormDialog = openerp.web.Dialog.extend({ openerp.web.form = {}; openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({ - init: function(parent, element_id, form_view) { - this._super(parent, element_id); + init: function(parent, form_view) { + var $section = parent.add_section(_t('Attachments'), 'attachments'); + this.$div = $('
'); + $section.append(this.$div); + + this._super(parent, $section.attr('id')); this.view = form_view; }, do_update: function() { @@ -564,7 +594,7 @@ openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({ }, on_attachments_loaded: function(attachments) { this.attachments = attachments; - this.$element.html(QWeb.render('FormView.sidebar.attachments', this)); + this.$div.html(QWeb.render('FormView.sidebar.attachments', this)); this.$element.find('.oe-binary-file').change(this.on_attachment_changed); this.$element.find('.oe-sidebar-attachment-delete').click(this.on_attachment_delete); }, @@ -918,7 +948,7 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({ return self.on_confirmed(); } }; - if (!this.node.attrs.special && (this.view.dirty_for_user || !this.view.datarecord.id)) { + if (!this.node.attrs.special) { return this.view.recursive_save().pipe(exec_action); } else { return exec_action(); @@ -1857,6 +1887,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({ this._super(view, node); this.is_started = $.Deferred(); this.form_last_update = $.Deferred(); + this.init_form_last_update = this.form_last_update; this.disable_utility_classes = true; }, start: function() { @@ -1898,7 +1929,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({ form: 'openerp.web.form.One2ManyFormView' }); var once = $.Deferred().then(function() { - self.form_last_update.resolve(); + self.init_form_last_update.resolve(); }); this.viewmanager.on_controller_inited.add_last(function(view_type, controller) { if (view_type == "list") { @@ -1932,9 +1963,10 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({ if (this.dataset.index === null && this.dataset.ids.length >= 1) { this.dataset.index = 0; } - this.form_last_update.then(function() { - this.form_last_update = view.do_show(); - }); + var act = function() { + return view.do_show(); + } + this.form_last_update = this.form_last_update.pipe(act, act);; } else if (self.viewmanager.active_view === "graph") { view.do_search(this.build_domain(), this.dataset.get_context(), []); } @@ -2025,9 +2057,10 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({ var view = this.viewmanager.views[this.viewmanager.active_view].controller; if (this.viewmanager.active_view === "form") { var res = $.when(view.do_save()); - if (!res.isResolved() && !res.isRejected()) { - throw "Asynchronous get_value() is not supported in form view."; - } + // it seems line there are some cases when this happens + /*if (!res.isResolved() && !res.isRejected()) { + console.warn("Asynchronous get_value() is not supported in form view."); + }*/ return res; } } @@ -2039,6 +2072,8 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({ }, validate: function() { this.invalid = false; + if (!this.viewmanager.views[this.viewmanager.active_view]) + return; var view = this.viewmanager.views[this.viewmanager.active_view].controller; if (this.viewmanager.active_view === "form") { for (var f in view.fields) { @@ -2362,13 +2397,17 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope var $nbutton = $buttons.find(".oe_selectcreatepopup-form-save-new"); $nbutton.click(function() { $.when(self.view_form.do_save()).then(function() { - self.view_form.on_button_new(); + self.view_form.reload_lock.then(function() { + self.view_form.on_button_new(); + }); }); }); var $nbutton = $buttons.find(".oe_selectcreatepopup-form-save"); $nbutton.click(function() { $.when(self.view_form.do_save()).then(function() { - self.check_exit(); + self.view_form.reload_lock.then(function() { + self.check_exit(); + }); }); }); var $cbutton = $buttons.find(".oe_selectcreatepopup-form-close"); diff --git a/addons/web/static/src/js/view_tree.js b/addons/web/static/src/js/view_tree.js index 78818c069c0..5143adb3838 100644 --- a/addons/web/static/src/js/view_tree.js +++ b/addons/web/static/src/js/view_tree.js @@ -110,7 +110,7 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView# } }); - if (this.fields_view.arch.attrs.colors) { + if (!this.fields_view.arch.attrs.colors) { return; } this.colors = _(this.fields_view.arch.attrs.colors.split(';')).chain() diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 04415166de2..8976887035a 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -121,6 +121,12 @@ db.web.ActionManager = db.web.Widget.extend({ if (!this.dialog && on_closed) { on_closed(); } + if (this.dialog && action.context) { + var model = action.context.active_model; + if (model === 'base.module.upgrade' || model === 'base.setup.installer') { + db.webclient.menu.reload(); + } + } this.dialog_stop(); }, ir_actions_server: function (action, on_closed) { @@ -514,9 +520,57 @@ db.web.Sidebar = db.web.Widget.extend({ self.do_toggle(); }); }, + + call_default_on_sidebar: function(item) { + var func_name = 'on_sidebar_' + _.underscored(item.label); + var fn = this.widget_parent[func_name]; + if(typeof fn === 'function') { + fn(item); + } + }, + + add_default_sections: function() { + this.add_section(_t('Customize'), 'customize'); + this.add_items('customize', [ + { + label: _t("Manage Views"), + callback: this.call_default_on_sidebar, + title: _t("Manage views of the current object"), + }, { + label: _t("Edit Workflow"), + callback: this.call_default_on_sidebar, + title: _t("Manage views of the current object"), + classname: 'oe_hide oe_sidebar_edit_workflow' + }, { + label: _t("Customize Object"), + callback: this.call_default_on_sidebar, + title: _t("Manage views of the current object"), + } + ]); + + this.add_section(_t('Other Options'), 'other'); + this.add_items('other', [ + { + label: _t("Import"), + callback: this.call_default_on_sidebar, + }, { + label: _t("Export"), + callback: this.call_default_on_sidebar, + }, { + label: _t("Translate"), + callback: this.call_default_on_sidebar, + classname: 'oe_sidebar_translate oe_hide' + }, { + label: _t("View Log"), + callback: this.call_default_on_sidebar, + classname: 'oe_hide oe_sidebar_view_log' + } + ]); + }, + add_toolbar: function(toolbar) { var self = this; - _.each([['print', "Reports"], ['action', "Actions"], ['relate', "Links"]], function(type) { + _.each([['print', _t("Reports")], ['action', _t("Actions")], ['relate', _t("Links")]], function(type) { var items = toolbar[type[0]]; if (items.length) { for (var i = 0; i < items.length; i++) { @@ -526,15 +580,30 @@ db.web.Sidebar = db.web.Widget.extend({ classname: 'oe_sidebar_' + type[0] } } - self.add_section(type[0], type[1], items); + self.add_section(type[1], type[0]); + self.add_items(type[0], items); } }); }, - add_section: function(code, name, items) { - // For each section, we pass a name/label and optionally an array of items. - // If no items are passed, then the section will be created as a custom section - // returning back an element_id to be used by a custom controller. - // Else, the section is a standard section with items displayed as links. + + add_section: function(name, code) { + if(!code) code = _.underscored(name); + var $section = this.sections[code]; + + if(!$section) { + section_id = _.uniqueId(this.element_id + '_section_' + code + '_'); + var $section = $(db.web.qweb.render("Sidebar.section", { + section_id: section_id, + name: name, + classname: 'oe_sidebar_' + code, + })); + $section.appendTo(this.$element.find('div.sidebar-actions')); + this.sections[code] = $section; + } + return $section; + }, + + add_items: function(section_code, items) { // An item is a dictonary : { // label: label to be displayed for the link, // action: action to be launch when the link is clicked, @@ -543,25 +612,24 @@ db.web.Sidebar = db.web.Widget.extend({ // title: optional title for the link // } // Note: The item should have one action or/and a callback + // + var self = this, - section_id = _.uniqueId(this.element_id + '_section_' + code + '_'); + $section = this.add_section(_.titleize(section_code.replace('_', ' ')), section_code), + section_id = $section.attr('id'); + if (items) { for (var i = 0; i < items.length; i++) { items[i].element_id = _.uniqueId(section_id + '_item_'); this.items[items[i].element_id] = items[i]; } - } - var $section = $(db.web.qweb.render("Sidebar.section", { - section_id: section_id, - name: name, - classname: 'oe_sidebar_' + code, - items: items - })); - if (items) { - $section.find('a.oe_sidebar_action_a').click(function() { + + var $items = $(db.web.qweb.render("Sidebar.section.items", {items: items})); + + $items.find('a.oe_sidebar_action_a').click(function() { var item = self.items[$(this).attr('id')]; if (item.callback) { - item.callback(); + item.callback.apply(self, [item]); } if (item.action) { var ids = self.widget_parent.get_selected_ids(); @@ -591,10 +659,13 @@ db.web.Sidebar = db.web.Widget.extend({ } return false; }); + + var $ul = $section.find('ul'); + if(!$ul.length) { + $ul = $(' - +