diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 0a3d24d41f4..2e26de30d5f 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -2180,9 +2180,33 @@ height: auto; line-height: 16px; } +.openerp .oe_form_field_one2many .oe_list_buttons.oe_editing .oe_list_save { + visibility: hidden; +} .openerp .oe_form .oe_form_field_many2many > .oe_list .oe_list_pager_single_page { display: none; } +.openerp .oe_list_buttons .oe_list_save, .openerp .oe_list_buttons .oe_list_discard { + display: none; +} +.openerp .oe_list_buttons.oe_editing .oe_list_add, .openerp .oe_list_buttons.oe_editing .oe_list_button_import { + display: none; +} +.openerp .oe_list_buttons.oe_editing .oe_list_save { + display: inline-block; +} +.openerp .oe_list_buttons.oe_editing .oe_list_discard { + display: inline; +} +.openerp .oe_list { + position: relative; +} +.openerp .oe_list .oe_form .oe_form_field { + width: auto; + position: absolute; + margin: 0 !important; + padding: 0; +} .openerp .oe_list_content { width: 100%; } @@ -2240,6 +2264,7 @@ } .openerp .oe_list_content > tbody > tr > td.oe_list_field_cell { padding: 3px 6px; + white-space: pre-line; } .openerp .oe_list_content > tbody > tr > td.oe_list_field_cell progress { width: 100%; @@ -2290,9 +2315,6 @@ .openerp .oe_list_content .numeric input { text-align: right; } -.openerp .oe_list_content .oe_list_edit_row_save:before { - content: "S"; -} .openerp .oe_trad_field.touched { border: 1px solid green !important; } @@ -2419,6 +2441,19 @@ .kitten-mode-activated > * { opacity: 0.7; } +.kitten-mode-activated .oe_footer a { + background-image: url(http://www.risacher.com/la-rache/zfiles/la-rache.png); + font-size: 1px; + letter-spacing: -1px; + color: transparent; + display: inline-block; + height: 15px; + width: 80px; + vertical-align: top; +} +.kitten-mode-activated .oe_footer a span { + display: none; +} div.ui-widget-overlay { background: black; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index fb67945a02d..c4314923867 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -92,9 +92,8 @@ $sheet-max-width: 860px letter-spacing: -1px color: transparent &:before - font-family: "mnmliconsRegular" + font: 21px "mnmliconsRegular" content: $icon-name - font-size: 20px color: $color // }}} @@ -1721,6 +1720,9 @@ $sheet-max-width: 860px li height: auto line-height: 16px + .oe_list_buttons.oe_editing .oe_list_save + // keep "save row" button hidden in o2m + visibility: hidden // }}} // FormView.many2many {{{ .oe_form .oe_form_field_many2many > .oe_list @@ -1728,6 +1730,25 @@ $sheet-max-width: 860px display: none // }}} // ListView {{{ + .oe_list_buttons + .oe_list_save, .oe_list_discard + display: none + &.oe_editing + .oe_list_add, .oe_list_button_import + display: none + .oe_list_save + display: inline-block + .oe_list_discard + display: inline + + .oe_list + position: relative + .oe_form .oe_form_field + width: auto + position: absolute + margin: 0 !important // dammit + padding: 0 + .oe_list_content width: 100% td:first-child, th:first-child @@ -1771,8 +1792,7 @@ $sheet-max-width: 860px border-top: 1px solid #ddd > td.oe_list_field_cell padding: 3px 6px - progress - width: 100% + white-space: pre-line > td, > th > button border: none @@ -1800,8 +1820,6 @@ $sheet-max-width: 860px width: 82px input text-align: right - .oe_list_edit_row_save:before - content: "S" // }}} // Translation {{{ .oe_trad_field.touched @@ -1910,6 +1928,7 @@ $sheet-max-width: 860px background-attachment: fixed >* opacity: 0.70 + // }}} div.ui-widget-overlay diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 40cff06e66a..71010ef6d74 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -135,8 +135,12 @@ instance.web.Dialog = instance.web.Widget.extend({ this.$element.dialog('close'); }, on_close: function() { + if (this.__tmp_dialog_destroying) + return; if (this.dialog_options.destroy_on_close) { + this.__tmp_dialog_closing = true; this.destroy(); + this.__tmp_dialog_closing = undefined; } }, on_resized: function() { @@ -145,6 +149,11 @@ instance.web.Dialog = instance.web.Widget.extend({ _.each(this.getChildren(), function(el) { el.destroy(); }); + if (! this.__tmp_dialog_closing) { + this.__tmp_dialog_destroying = true; + this.close(); + this.__tmp_dialog_destroying = undefined; + } if (! this.isDestroyed()) { this.$element.dialog('destroy'); } @@ -254,7 +263,11 @@ instance.web.Loading = instance.web.Widget.extend({ this.count += increment; if (this.count > 0) { - this.$element.text(_.str.sprintf( _t("Loading (%d)"), this.count)); + if (instance.connection.debug) { + this.$element.text(_.str.sprintf( _t("Loading (%d)"), this.count)); + } else { + this.$element.text(_t("Loading")); + } this.$element.show(); this.getParent().$element.addClass('oe_wait'); } else { @@ -957,10 +970,12 @@ instance.web.WebClient = instance.web.Client.extend({ }, show_login: function() { var self = this; + self.$('.oe_topbar').hide(); self.login.appendTo(self.$element); }, show_application: function() { var self = this; + self.$('.oe_topbar').show(); self.login.$element.hide(); self.menu = new instance.web.Menu(self); self.menu.replace(this.$element.find('.oe_menu_placeholder')); diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index c8b6f797dba..504510ef133 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -1669,6 +1669,7 @@ instance.web.search.AddToDashboard = instance.web.Widget.extend({ return $.when(this.load_data(),this.data_loaded).pipe(this.proxy("render_data")); }, load_data:function(){ + if (!instance.webclient) { return $.Deferred().reject(); } var self = this,dashboard_menu = instance.webclient.menu.data.data.children; var ir_model_data = new instance.web.Model('ir.model.data',{},[['name','=','menu_reporting_dashboard']]).query(['res_id']); var map_data = function(result){ diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index d6ed85fedad..677b7cf7c4e 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -239,6 +239,13 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM } } }, + /** + * + * @param {Object} [options] + * @param {Boolean} [editable=false] whether the form should be switched to edition mode. A value of ``false`` will keep the current mode. + * @param {Boolean} [reload=true] whether the form should reload its content on show, or use the currently loaded record + * @return {$.Deferred} + */ do_show: function (options) { var self = this; options = options || {}; @@ -253,23 +260,24 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM } this.$element.show().css('visibility', 'hidden'); this.$element.add(this.$buttons).removeClass('oe_form_dirty'); - return this.has_been_loaded.pipe(function() { - var result; - if (self.dataset.index === null) { - // null index means we should start a new record - result = self.on_button_new(); - } else { - result = self.dataset.read_index(_.keys(self.fields_view.fields), { - context : { 'bin_size' : true } - }).pipe(self.on_record_loaded); - } - result.pipe(function() { - if (options.editable) { - self.set({mode: "edit"}); + + var shown = this.has_been_loaded; + if (options.reload !== false) { + shown = shown.pipe(function() { + if (self.dataset.index === null) { + // null index means we should start a new record + return self.on_button_new(); } - self.$element.css('visibility', 'visible'); + return self.dataset.read_index(_.keys(self.fields_view.fields), { + context: { 'bin_size': true } + }).pipe(self.on_record_loaded); }); - return result; + } + return shown.pipe(function() { + if (options.editable) { + self.set({mode: "edit"}); + } + self.$element.css('visibility', 'visible'); }); }, do_hide: function () { @@ -330,6 +338,20 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM self.$element.add(self.$buttons).removeClass('oe_form_dirty'); }); }, + /** + * Loads and sets up the default values for the model as the current + * record + * + * @return {$.Deferred} + */ + load_defaults: function () { + var keys = _.keys(this.fields_view.fields); + if (keys.length) { + return this.dataset.default_get(keys) + .pipe(this.on_record_loaded); + } + return this.on_record_loaded({}); + }, on_form_changed: function() { this.trigger("view_content_has_changed"); }, @@ -600,22 +622,11 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM on_button_new: function() { var self = this; this.set({mode: "edit"}); - var def = $.Deferred(); - $.when(this.has_been_loaded).then(function() { + return $.when(this.has_been_loaded).pipe(function() { if (self.can_be_discarded()) { - var keys = _.keys(self.fields_view.fields); - if (keys.length) { - self.dataset.default_get(keys).pipe(self.on_record_loaded).then(function() { - def.resolve(); - }); - } else { - self.on_record_loaded({}).then(function() { - def.resolve(); - }); - } + return self.load_defaults(); } }); - return def.promise(); }, on_button_edit: function() { return this.set({mode: "edit"}); @@ -674,6 +685,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM values = {}, first_invalid_field = null; for (var f in self.fields) { + if (!self.fields.hasOwnProperty(f)) { continue; } f = self.fields[f]; if (!f.is_valid()) { form_invalid = true; @@ -689,8 +701,9 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM } if (form_invalid) { self.set({'display_invalid_fields': true}); - for (var f in self.fields) { - self.fields[f]._check_css_flags(); + for (var g in self.fields) { + if (!self.fields.hasOwnProperty(g)) { continue; } + self.fields[g]._check_css_flags(); } first_invalid_field.focus(); self.on_invalid(); @@ -722,14 +735,15 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM });}); }, on_invalid: function() { - var msg = ""; - this.do_warn("The following fields are invalid :", msg); + var warnings = _(this.fields).chain() + .filter(function (f) { return !f.is_valid(); }) + .map(function (f) { + return _.str.sprintf('
  • %s
  • ', + _.escape(f.string)); + }).value(); + warnings.unshift(''); + this.do_warn("The following fields are invalid :", warnings.join('')); }, on_saved: function(r, success) { if (!r.result) { @@ -807,10 +821,10 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM var ids = this.get_selected_ids(); values["id"] = ids.length > 0 ? ids[0] : false; _.each(this.fields, function(value_, key) { - if (_.include(blacklist, key)) + if (_.include(blacklist, key)) { return; - var val = value_.get_value(); - values[key] = val; + } + values[key] = value_.get_value(); }); return values; }, @@ -945,6 +959,9 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM is_create_mode: function() { return !this.datarecord.id; }, + open_translate_dialog: function(field) { + return this._super(field); + }, }); /** @@ -988,7 +1005,6 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt } }); } - selector = 'form[version!="7.0"] page,form[version!="7.0"]'; }, render_to: function($target) { var self = this; @@ -1122,7 +1138,7 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt if (found) return; - $label = $('