diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index d0c8950f9e1..96db9c6fc3c 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -291,7 +291,7 @@ class Session(openerpweb.Controller): @openerpweb.jsonrequest def login(self, req, db, login, password): req.session.login(db, login, password) - ctx = req.session.get_context() + ctx = req.session.get_context() if req.session._uid else {} return { "session_id": req.session_id, diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index d7624493fdc..c75fe786543 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -892,6 +892,9 @@ label.error { .openerp .oe_forms input.field_datetime { min-width: 11em; } +.openerp .oe_forms.oe_frame .oe_datepicker_root { + width: 100%; +} .openerp .oe_forms .button { color: #4c4c4c; white-space: nowrap; @@ -904,7 +907,14 @@ label.error { position: absolute; cursor: pointer; right: 5px; - top: 5px; + top: 3px; +} +.openerp .oe_datepicker_root { + position: relative; + display: inline-block; +} +.openerp .oe_datepicker_root input[type="text"] { + min-width: 160px; } .openerp .oe_input_icon_disabled { position: absolute; diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 8a8962fd27b..7a48c00b4fe 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -581,7 +581,6 @@ openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# * this._super(parent); this.qs = "?" + jQuery.param.querystring(); this.$content = $(); - console.debug("initializing header with id", this.element_id); this.update_promise = $.Deferred().resolve(); }, start: function() { @@ -702,10 +701,11 @@ openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# * }, Save: function(){ var inner_viewmanager = action_manager.inner_viewmanager; - inner_viewmanager.views[inner_viewmanager.active_view].controller.do_save(function(){ - inner_viewmanager.start(); + inner_viewmanager.views[inner_viewmanager.active_view].controller.do_save() + .then(function() { + self.dialog.stop(); + window.location.reload(); }); - $(this).dialog('destroy') } } }); @@ -728,21 +728,13 @@ openerp.web.Header = openerp.web.Widget.extend(/** @lends openerp.web.Header# * submitHandler: function (form) { self.rpc("/web/session/change_password",{ 'fields': $(form).serializeArray() - }, function(result) { - if (result.error) { - self.display_error(result); + }, function(result) { + if (result.error) { + self.display_error(result); return; - } - else { - if (result.new_password) { - self.session.password = result.new_password; - var session = new openerp.web.Session(self.session.server, self.session.port); - session.start(); - session.session_login(self.session.db, self.session.login, self.session.password) - } - } - self.notification.notify("Changed Password", "Password has been changed successfully"); - self.dialog.close(); + } else { + self.session.logout(); + } }); } }); @@ -963,7 +955,6 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie this.session.start(); this.login.start(); this.menu.start(); - console.debug("The openerp client has been initialized."); }, on_logged: function() { if(this.action_manager) diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index a33fca458d0..2e9294ded12 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -1,7 +1,10 @@ /*--------------------------------------------------------- * OpenERP Web core *--------------------------------------------------------*/ - +var console; +if (!console) { + console = {log: function () {}}; +} if (!console.debug) { console.debug = console.log; } @@ -483,7 +486,8 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web self.user_context = result.context; self.db = result.db; self.session_save(); - self.on_session_valid(); + if (self.uid) + self.on_session_valid(); return true; }).then(success_callback); }, @@ -771,7 +775,6 @@ openerp.web.SessionAware = openerp.web.CallbackEnabled.extend(/** @lends openerp * // stuff that you want to init before the rendering * }, * start: function() { - * this._super(); * // stuff you want to make after the rendering, `this.$element` holds a correct value * this.$element.find(".my_button").click(/* an example of event binding * /); * @@ -915,6 +918,8 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg * @returns {jQuery.Deferred} */ start: function() { + /* The default implementation is only useful for retro-compatibility, it is + not necessary to call it using _super() when using Widget for new components. */ if (!this.$element) { var tmp = document.getElementById(this.element_id); this.$element = tmp ? $(tmp) : undefined; @@ -922,7 +927,7 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg return $.Deferred().done().promise(); }, /** - * Destroys the current widget, also destory all its children before destroying itself. + * Destroys the current widget, also destroy all its children before destroying itself. */ stop: function() { _.each(_.clone(this.widget_children), function(el) { @@ -943,7 +948,6 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg * If that's not the case this method will simply return `false`. */ do_action: function(action, on_finished) { - console.log('Widget.do_action', action, on_finished); if (this.widget_parent) { return this.widget_parent.do_action(action, on_finished); } diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 925490b7459..e7feedf26a5 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -118,26 +118,26 @@ openerp.web.parse_value = function (value, descriptor, value_if_empty) { var tmp = Date.parseExact(value, _.sprintf("%s %s", Date.CultureInfo.formatPatterns.shortDate, Date.CultureInfo.formatPatterns.longTime)); if (tmp !== null) - return tmp; + return openerp.web.datetime_to_str(tmp); tmp = Date.parse(value); if (tmp !== null) - return tmp; + return openerp.web.datetime_to_str(tmp); throw value + " is not a valid datetime"; case 'date': var tmp = Date.parseExact(value, Date.CultureInfo.formatPatterns.shortDate); if (tmp !== null) - return tmp; + return openerp.web.date_to_str(tmp); tmp = Date.parse(value); if (tmp !== null) - return tmp; + return openerp.web.date_to_str(tmp); throw value + " is not a valid date"; case 'time': var tmp = Date.parseExact(value, Date.CultureInfo.formatPatterns.longTime); if (tmp !== null) - return tmp; + return openerp.web.time_to_str(tmp); tmp = Date.parse(value); if (tmp !== null) - return tmp; + return openerp.web.time_to_str(tmp); throw value + " is not a valid time"; } return value; diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 94143d4bbfa..db91d6bfd27 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -795,20 +795,18 @@ openerp.web.search.BooleanField = openerp.web.search.SelectionField.extend(/** @ * @extends openerp.web.search.DateField */ openerp.web.search.DateField = openerp.web.search.Field.extend(/** @lends openerp.web.search.DateField# */{ - /** - * enables date picker on the HTML widgets - */ + template: "SearchView.date", start: function () { this._super(); - this.$element.addClass('field_date').datepicker({ - dateFormat: 'yy-mm-dd' - }); - }, - stop: function () { - this.$element.datepicker('destroy'); + this.datewidget = new openerp.web.DateWidget(this); + this.datewidget.prependTo(this.$element); + this.datewidget.$element.find("input").attr("size", 15); + this.datewidget.$element.find("input").attr("autofocus", + this.attrs.default_focus === '1' ? 'autofocus' : undefined); + this.datewidget.set_value(this.defaults[this.attrs.name] || false); }, get_value: function () { - return this.$element.val(); + return this.datewidget.get_value() || null; } }); /** @@ -1123,7 +1121,7 @@ openerp.web.search.ExtendedSearchProposition.Char = openerp.web.OldWidget.extend } }); openerp.web.search.ExtendedSearchProposition.DateTime = openerp.web.OldWidget.extend({ - template: 'SearchView.extended_search.proposition.datetime', + template: 'SearchView.extended_search.proposition.empty', identifier_prefix: 'extended-search-proposition-datetime', operators: [ {value: "=", text: "is equal to"}, @@ -1134,18 +1132,16 @@ openerp.web.search.ExtendedSearchProposition.DateTime = openerp.web.OldWidget.ex {value: "<=", text: "less or equal than"} ], get_value: function() { - return this.$element.val(); + return this.datewidget.get_value(); }, start: function() { this._super(); - this.$element.datetimepicker({ - dateFormat: 'yy-mm-dd', - timeFormat: 'hh:mm:ss' - }); + this.datewidget = new openerp.web.DateTimeWidget(this); + this.datewidget.prependTo(this.$element); } }); openerp.web.search.ExtendedSearchProposition.Date = openerp.web.OldWidget.extend({ - template: 'SearchView.extended_search.proposition.date', + template: 'SearchView.extended_search.proposition.empty', identifier_prefix: 'extended-search-proposition-date', operators: [ {value: "=", text: "is equal to"}, @@ -1156,14 +1152,12 @@ openerp.web.search.ExtendedSearchProposition.Date = openerp.web.OldWidget.extend {value: "<=", text: "less or equal than"} ], get_value: function() { - return this.$element.val(); + return this.datewidget.get_value(); }, start: function() { this._super(); - this.$element.datepicker({ - dateFormat: 'yy-mm-dd', - timeFormat: 'hh:mm:ss' - }); + this.datewidget = new openerp.web.DateWidget(this); + this.datewidget.prependTo(this.$element); } }); openerp.web.search.ExtendedSearchProposition.Integer = openerp.web.OldWidget.extend({ diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 31779648f3b..2c730d0b5af 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -1007,19 +1007,18 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f * the fields'context with the action's context. */ build_context: function() { - // I previously belevied contexts should be herrited, but now I doubt it - //var a_context = this.view.dataset.get_context() || {}; var f_context = this.field.context || null; // maybe the default_get should only be used when we do a default_get? - var v_context1 = this.node.attrs.default_get || {}; - var v_context2 = this.node.attrs.context || {}; - var v_context = new openerp.web.CompoundContext(v_context1, v_context2); - if (v_context1.__ref || v_context2.__ref || true) { //TODO niv: remove || true + var v_contexts = _.compact([this.node.attrs.default_get || null, + this.node.attrs.context || null]); + var v_context = new openerp.web.CompoundContext(); + _.each(v_contexts, function(x) {v_context.add(x);}); + if (_.detect(v_contexts, function(x) {return !!x.__ref;})) { var fields_values = this._build_view_fields_values(); v_context.set_eval_context(fields_values); } // if there is a context on the node, overrides the model's context - var ctx = f_context || v_context; + var ctx = v_contexts.length > 0 ? v_context : f_context; return ctx; }, build_domain: function() { @@ -1121,16 +1120,13 @@ openerp.web.form.FieldFloat = openerp.web.form.FieldChar.extend({ } }); -openerp.web.form.FieldDatetime = openerp.web.form.Field.extend({ - init: function(view, node) { - this._super(view, node); - this.template = "FieldDate"; - this.jqueryui_object = 'datetimepicker'; - }, +openerp.web.DateTimeWidget = openerp.web.Widget.extend({ + template: "web.datetimepicker", + jqueryui_object: 'datetimepicker', + type_of_date: "datetime", start: function() { var self = this; - this._super.apply(this, arguments); - this.$element.find('input').change(this.on_ui_change); + this.$element.find('input').change(this.on_change); this.picker({ onSelect: this.on_picker_select, changeMonth: true, @@ -1148,6 +1144,8 @@ openerp.web.form.FieldDatetime = openerp.web.form.Field.extend({ this.$element.find('button.oe_datepicker_close').click(function() { self.$element.find('.oe_datepicker').hide(); }); + this.set_readonly(false); + this.value = false; }, picker: function() { return $.fn[this.jqueryui_object].apply(this.$element.find('.oe_datepicker_container'), arguments); @@ -1157,60 +1155,93 @@ openerp.web.form.FieldDatetime = openerp.web.form.Field.extend({ this.$element.find('input').val(date ? this.format_client(date) : '').change(); }, set_value: function(value) { - value = this.parse(value); - this._super(value); + this.value = value; this.$element.find('input').val(value ? this.format_client(value) : ''); }, get_value: function() { - return this.format(this.value); + return this.value; }, set_value_from_ui: function() { var value = this.$element.find('input').val() || false; this.value = this.parse_client(value); - this._super(); }, - update_dom: function() { - this._super.apply(this, arguments); + set_readonly: function(readonly) { + this.readonly = readonly; this.$element.find('input').attr('disabled', this.readonly); - this.$element.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', this.readonly); + this.$element.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', readonly); }, - validate: function() { - this.invalid = false; + is_valid: function(required) { var value = this.$element.find('input').val(); if (value === "") { - this.invalid = this.required; + return !required; } else { try { this.parse_client(value); - this.invalid = false; + return true; } catch(e) { - this.invalid = true; + return false; } } }, focus: function() { this.$element.find('input').focus(); }, - parse: openerp.web.auto_str_to_date, parse_client: function(v) { - return openerp.web.parse_value(v, this.field); - }, - format: function(val) { - return openerp.web.auto_date_to_str(val, this.field.type); + return openerp.web.parse_value(v, {"widget": this.type_of_date}); }, format_client: function(v) { - return openerp.web.format_value(v, this.field); + return openerp.web.format_value(v, {"widget": this.type_of_date}); + }, + on_change: function() { + if (this.is_valid()) { + this.set_value_from_ui(); + } + } +}); + +openerp.web.DateWidget = openerp.web.DateTimeWidget.extend({ + jqueryui_object: 'datepicker', + type_of_date: "date", + on_picker_select: function(text, instance) { + this._super(text, instance); + this.$element.find('.oe_datepicker').hide(); + } +}); + +openerp.web.form.FieldDatetime = openerp.web.form.Field.extend({ + template: "EmptyComponent", + build_widget: function() { + return new openerp.web.DateTimeWidget(this); + }, + start: function() { + var self = this; + this._super.apply(this, arguments); + this.datewidget = this.build_widget(); + this.datewidget.on_change.add(this.on_ui_change); + this.datewidget.appendTo(this.$element); + }, + set_value: function(value) { + this._super(value); + this.datewidget.set_value(value); + }, + get_value: function() { + return this.datewidget.get_value(); + }, + update_dom: function() { + this._super.apply(this, arguments); + this.datewidget.set_readonly(this.readonly); + }, + validate: function() { + this.invalid = !this.datewidget.is_valid(this.required); + }, + focus: function() { + this.datewidget.focus(); } }); openerp.web.form.FieldDate = openerp.web.form.FieldDatetime.extend({ - init: function(view, node) { - this._super(view, node); - this.jqueryui_object = 'datepicker'; - }, - on_picker_select: function(text, instance) { - this._super(text, instance); - this.$element.find('.oe_datepicker').hide(); + build_widget: function() { + return new openerp.web.DateWidget(this); } }); diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index f8a89cd34a1..eeda44c4c99 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -415,8 +415,8 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView# */ do_search: function (domains, contexts, groupbys) { return this.rpc('/web/session/eval_domain_and_context', { - domains: [this.dataset.get_domain()].concat(domains), - contexts: [this.dataset.get_context()].concat(contexts), + domains: _([this.dataset.get_domain()].concat(domains)).compact(), + contexts: _([this.dataset.get_context()].concat(contexts)).compact(), group_by_seq: groupbys }, $.proxy(this, 'do_actual_search')); }, @@ -541,6 +541,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView# if (_.isEmpty(records)) { records = this.groups.get_records(); } + records = _(records).compact(); var count = 0, sums = {}; _(columns).each(function (column) { @@ -1235,6 +1236,9 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L }, get_records: function () { if (_(this.children).isEmpty()) { + if (!this.datagroup.length) { + return; + } return { count: this.datagroup.length, values: this.datagroup.aggregates diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 3870ef43b67..a451912dcb8 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -800,13 +800,15 @@ > - - - -