diff options
Diffstat (limited to 'addons/web/static/src/js')
| -rw-r--r-- | addons/web/static/src/js/chrome.js | 30 | ||||
| -rw-r--r-- | addons/web/static/src/js/core.js | 19 | ||||
| -rw-r--r-- | addons/web/static/src/js/data_export.js | 16 | ||||
| -rw-r--r-- | addons/web/static/src/js/formats.js | 48 | ||||
| -rw-r--r-- | addons/web/static/src/js/search.js | 1 | ||||
| -rw-r--r-- | addons/web/static/src/js/tour.js | 84 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_form.js | 118 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_list.js | 1 | ||||
| -rw-r--r-- | addons/web/static/src/js/views.js | 8 |
9 files changed, 215 insertions, 110 deletions
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index f5f8129d502..608f76cd6ca 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -115,6 +115,7 @@ instance.web.Dialog = instance.web.Widget.extend({ this.init_dialog(); } this.$buttons.insertAfter(this.$dialog_box.find(".modal-body")); + $('.tooltip').remove(); //remove open tooltip if any to prevent them staying when modal is opened //add to list of currently opened modal opened_modal.push(this.$dialog_box); return this; @@ -185,12 +186,12 @@ instance.web.Dialog = instance.web.Widget.extend({ close: function(reason) { if (this.dialog_inited && !this.__tmp_dialog_hiding) { $('.tooltip').remove(); //remove open tooltip if any to prevent them staying when modal has disappeared - this.trigger("closing", reason); if (this.$el.is(":data(bs.modal)")) { // may have been destroyed by closing signal this.__tmp_dialog_hiding = true; this.$dialog_box.modal('hide'); this.__tmp_dialog_hiding = undefined; } + this.trigger("closing", reason); } }, _closing: function() { @@ -230,6 +231,9 @@ instance.web.Dialog = instance.web.Widget.extend({ if (opened_modal.length > 0){ //we still have other opened modal so we should focus it opened_modal[opened_modal.length-1].focus(); + //keep class modal-open (deleted by bootstrap hide fnct) on body + //to allow scrolling inside the modal + $('body').addClass('modal-open'); } },0); } @@ -252,7 +256,7 @@ instance.web.CrashManager = instance.web.Class.extend({ return; } if (error.data.name === "openerp.http.SessionExpiredException" || error.data.name === "werkzeug.exceptions.Forbidden") { - this.show_warning({type: "Session Expired", data: { message: _t("Your OpenERP session expired. Please refresh the current web page.") }}); + this.show_warning({type: "Session Expired", data: { message: _t("Your Odoo session expired. Please refresh the current web page.") }}); return; } if (error.data.exception_type === "except_osv" || error.data.exception_type === "warning" || error.data.exception_type === "access_error") { @@ -270,7 +274,7 @@ instance.web.CrashManager = instance.web.Class.extend({ } new instance.web.Dialog(this, { size: 'medium', - title: "OpenERP " + (_.str.capitalize(error.type) || "Warning"), + title: "Odoo " + (_.str.capitalize(error.type) || "Warning"), buttons: [ {text: _t("Ok"), click: function() { this.parents('.modal').modal('hide'); }} ], @@ -285,7 +289,7 @@ instance.web.CrashManager = instance.web.Class.extend({ this.parents('.modal').modal('hide'); }; new instance.web.Dialog(this, { - title: "OpenERP " + _.str.capitalize(error.type), + title: "Odoo " + _.str.capitalize(error.type), buttons: buttons }, QWeb.render('CrashManager.error', {session: instance.session, error: error})).open(); }, @@ -337,7 +341,7 @@ instance.web.RedirectWarningHandler = instance.web.Dialog.extend(instance.web.Ex new instance.web.Dialog(this, { size: 'medium', - title: "OpenERP " + (_.str.capitalize(error.type) || "Warning"), + title: "Odoo " + (_.str.capitalize(error.type) || "Warning"), buttons: [ {text: _t("Ok"), click: function() { self.$el.parents('.modal').modal('hide'); self.destroy();}}, {text: error.data.arguments[2], @@ -910,7 +914,7 @@ instance.web.Menu = instance.web.Widget.extend({ } // add a tooltip to cropped menu items this.$secondary_menus.find('.oe_secondary_submenu li a span').each(function() { - $(this).tooltip(this.scrollWidth > this.clientWidth ? {title: $(this).text().trim(), placement: 'auto right'} :'destroy'); + $(this).tooltip(this.scrollWidth > this.clientWidth ? {title: $(this).text().trim(), placement: 'right'} :'destroy'); }); }, /** @@ -1156,12 +1160,19 @@ instance.web.Client = instance.web.Widget.extend({ }, 0); }); instance.web.bus.on('click', this, function(ev) { - $.fn.tooltip('destroy'); + $('.tooltip').remove(); if (!$(ev.target).is('input[type=file]')) { self.$el.find('.oe_dropdown_menu.oe_opened, .oe_dropdown_toggle.oe_opened').removeClass('oe_opened'); } }); }, + on_logo_click: function(ev){ + if (!this.has_uncommitted_changes()) { + return; + } else { + ev.preventDefault(); + } + }, show_common: function() { var self = this; this.crashmanager = new instance.web.CrashManager(); @@ -1190,7 +1201,7 @@ instance.web.WebClient = instance.web.Client.extend({ this._current_state = null; this.menu_dm = new instance.web.DropMisordered(); this.action_mutex = new $.Mutex(); - this.set('title_part', {"zopenerp": "OpenERP"}); + this.set('title_part', {"zopenerp": "Odoo"}); }, start: function() { var self = this; @@ -1266,6 +1277,9 @@ instance.web.WebClient = instance.web.Client.extend({ self.logo_edit(ev); }); + this.$('.oe_logo img').click(function(ev) { + self.on_logo_click(ev); + }); // Menu is rendered server-side thus we don't want the widget to create any dom self.menu = new instance.web.Menu(self); self.menu.setElement(this.$el.parents().find('.oe_application_menu_placeholder')); diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 23645e22bf1..169547d78c0 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -311,9 +311,8 @@ instance.web.Session.include( /** @lends instance.web.Session# */{ self.module_list = all_modules; var loaded = self.load_translations(); - var datejs_locale = "/web/static/lib/datejs/globalization/" + self.user_context.lang.replace("_", "-") + ".js"; - - var file_list = [ datejs_locale ]; + var locale = "/web/webclient/locale/" + self.user_context.lang || 'en_US'; + var file_list = [ locale ]; if(to_load.length) { loaded = $.when( loaded, @@ -772,7 +771,7 @@ instance.web.unblockUI = function() { /* Bootstrap defaults overwrite */ $.fn.tooltip.Constructor.DEFAULTS.placement = 'auto top'; $.fn.tooltip.Constructor.DEFAULTS.html = true; -$.fn.tooltip.Constructor.DEFAULTS.container = 'body'; +$.fn.tooltip.Constructor.DEFAULTS.trigger = 'hover focus click'; //overwrite bootstrap tooltip method to prevent showing 2 tooltip at the same time var bootstrap_show_function = $.fn.tooltip.Constructor.prototype.show; $.fn.tooltip.Constructor.prototype.show = function () { @@ -786,6 +785,18 @@ $.fn.tooltip.Constructor.prototype.show = function () { if (e.isDefaultPrevented() || !inDom) return; return bootstrap_show_function.call(this); }; +//overwrite bootstrap tooltip init method in order to check if tooltip is in a modal or not and +//if so it needs to have a container body in order to be visible +var bootstrap_init_tooltip_fnct = $.fn.tooltip.Constructor.prototype.init; +$.fn.tooltip.Constructor.prototype.init = function (type, element, options) { + options = options || {} + if ($('.modal[aria-hidden="false"]').length !== 0){ + if (options && !options.container){ + options = _.extend({container: 'body'},options); + } + } + return bootstrap_init_tooltip_fnct.call(this, type, element, options); +} /** * Registry for all the client actions key: tag value: widget diff --git a/addons/web/static/src/js/data_export.js b/addons/web/static/src/js/data_export.js index 2f7ff81d089..a6cb35423fb 100644 --- a/addons/web/static/src/js/data_export.js +++ b/addons/web/static/src/js/data_export.js @@ -27,6 +27,8 @@ instance.web.DataExport = instance.web.Dialog.extend({ this.$('#fields_list').empty(); }, 'click #export_new_list': 'on_show_save_list', + 'click #move_up':'on_click_move_up', + 'click #move_down':'on_click_move_down', }, init: function(parent, dataset) { var self = this; @@ -79,6 +81,20 @@ instance.web.DataExport = instance.web.Dialog.extend({ this.rpc('/web/export/formats', {}).done(this.do_setup_export_formats), this.show_exports_list()); }, + on_click_move_up: function () { + var prev_row = this.$el.find('#fields_list option:selected').first().prev(); + if(prev_row.length){ + var selected_rows = self.$('#fields_list option:selected').detach(); + prev_row.before(selected_rows); + } + }, + on_click_move_down: function () { + var next_row = this.$el.find('#fields_list option:selected').last().next(); + if(next_row.length){ + var selected_rows = self.$('#fields_list option:selected').detach(); + next_row.after(selected_rows); + } + }, do_setup_export_formats: function (formats) { var $fmts = this.$el.find('#export_format'); _(formats).each(function (format) { diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 3d7b574e56a..14026f17681 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -361,4 +361,52 @@ instance.web.round_decimals = function(value, decimals){ return instance.web.round_precision(value, Math.pow(10,-decimals)); }; +/** ++ * ++ * convert python.strftime format into moment.js format ++ * inspired from : https://github.com/uruz/moment-datetime/blob/master/moment-datetime.js ++*/ +instance.web.convert_to_moment_format = function(format){ + if (!format) + return false; + var replacements = { + 'a': 'ddd', + 'A': 'dddd', + 'b': 'MMM', + 'B': 'MMMM', + //'c': //%c is defined too vaguely + 'd': 'DD', + //'f': JS have no support for microseconds and moment.js have no support for milliseconds + 'H': 'HH', + 'I': 'hh', + 'j': 'DDDD', + 'm': 'MM', + 'M': 'mm', + 'p': 'A', + 'S': 'ss', + 'U': 'ww',//ww is for Sunday-based week + 'w': 'd', + //'W': 'ww',//%W is weeknumber for weeks starting from Monday and it is not implemented in moment.js + //'x': + //'X': //%x and %X are defined too vaguely to be implemented + 'y': 'YY', + 'Y': 'YYYY', + 'z': 'ZZ', + //'Z': 'z', - moment.js does not support timezone names + '%': '%' + } + var moment_format = '', directive_index = 0, replacement, unformatted; + while (format.indexOf('%') !== -1){ + directive_index = format.indexOf('%') + 1; + replacement = replacements[format[directive_index]]; + unformatted = format.substr(0, directive_index-1); + if (unformatted.length){ + unformatted = '[' + unformatted.replace(/(\[|\])/g, '\\$&') +']'; + } + moment_format += unformatted + (replacement ? replacement : format[directive_index]); + format = format.substr(directive_index+1); + } + return moment_format; +}; + })(); diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 1bfdc86fb5a..566179c2a38 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -782,6 +782,7 @@ instance.web.SearchViewDrawer = instance.web.Widget.extend({ start: function() { var self = this; + if (this.searchview.headless) return $.when(this._super(), this.searchview.ready); var filters_ready = this.searchview.fields_view_get .then(this.proxy('prepare_filters')); return $.when(this._super(), filters_ready).then(function () { diff --git a/addons/web/static/src/js/tour.js b/addons/web/static/src/js/tour.js index fec189e06f5..0179d3eda65 100644 --- a/addons/web/static/src/js/tour.js +++ b/addons/web/static/src/js/tour.js @@ -329,18 +329,22 @@ var Tour = { } console.log(message); }, - error: function (step, message) { + logError: function (step, message, all) { var state = Tour.getState(); - message += '\n tour: ' + state.id - + (step ? '\n step: ' + step.id + ": '" + (step._title || step.title) + "'" : '' ) - + '\n href: ' + window.location.href - + '\n referrer: ' + document.referrer - + (step ? '\n element: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) : '' ) - + (step ? '\n waitNot: ' + Boolean(!step.waitNot || !$(step.waitNot).size()) : '' ) - + (step ? '\n waitFor: ' + Boolean(!step.waitFor || $(step.waitFor).size()) : '' ) - + "\n localStorage: " + JSON.stringify(localStorage) - + '\n\n' + $("body").html(); + message += '\ntour: ' + state.id + + (step ? '\nstep: ' + step.id + ": '" + (step._title || step.title) + "'" : '' ) + + (all ? '\nhref: ' + window.location.href : '' ) + + (all ? '\nreferrer: ' + document.referrer : '' ) + + (step ? '\nelement: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) : '' ) + + (step ? '\nwaitNot: ' + Boolean(!step.waitNot || !$(step.waitNot).size()) : '' ) + + (step ? '\nwaitFor: ' + Boolean(!step.waitFor || $(step.waitFor).size()) : '' ) + + (all ? "\nlocalStorage: " + JSON.stringify(localStorage) : '' ) + + (all ? '\n\n' + $("body").html() : '' ); Tour.log(message, true); + }, + error: function (step, message) { + var state = Tour.getState(); + Tour.logError(step, "Error: " + message, true); Tour.endTour(); }, lists: function () { @@ -403,7 +407,7 @@ var Tour = { var state = Tour.getState(); var time = new Date().getTime(); var timer; - var next = state.tour.steps[state.step.id+1]; + var next = state.step.next ? Tour.search_step(state.step.next) : state.tour.steps[state.step.id+1]; var overlaps = state.mode === "test" ? Tour.errorDelay : 0; window.onbeforeunload = function () { @@ -418,20 +422,65 @@ var Tour = { clearTimeout(Tour.timer); if (Tour.check(next)) { + clearTimeout(Tour.currentTimer); // use an other timeout for cke dom loading Tour.saveState(state.id, state.mode, state.step.id, 0); setTimeout(function () { + if (state.step.onend && Tour._goto(state.step.onend())) return; Tour.nextStep(next); }, Tour.defaultDelay); + return; + } else if (!overlaps || new Date().getTime() - time < overlaps) { + Tour.timer = setTimeout(checkNext, Tour.defaultDelay); - } else { - return Tour.error(next, "Can't reach the next step"); + return; + + } else if(next.onerror) { + + Tour.logError(next, "Error: Can't reach the next step (call next step onerror)", false); + var id = next.onerror(); + if (id) { + if (Tour._goto(id)) return; + if (id === true) { + Tour.nextStep(next); + return; + } + } + } + + Tour.error(next, "Can't reach the next step"); + return; + } setTimeout(checkNext, 0); }, + search_step: function (id_or_title) { + var state = Tour.getState(); + if (id_or_title !== undefined) { + if (isNaN(id_or_title)) { + for (var k=0; k<state.tour.steps.length; k++) { + if (state.tour.steps[k].title === id_or_title || state.tour.steps[k]._title === id_or_title) { + return state.tour.steps[k]; + } + } + } else { + return state.tour.steps[id_or_title]; + } + } + return undefined; + }, + _goto: function (id_or_title) { + var state = Tour.getState(); + if (!state) return true; + if (id_or_title === undefined) return false; + var step = Tour.search_step(id_or_title); + Tour.saveState(state.id, state.mode, step.id, 0); + Tour.nextStep(Tour.getState().step); + return true; + }, nextStep: function (step) { var state = Tour.getState(); @@ -440,7 +489,7 @@ var Tour = { } step = step || state.step; - var next = state.tour.steps[step.id+1]; + var next = state.step.next ? Tour.search_step(state.step.next) : state.tour.steps[step.id+1]; if (state.mode === "test" && state.number > 3) { return Tour.error(next, "Cycling. Can't reach the next step"); @@ -448,14 +497,15 @@ var Tour = { Tour.saveState(state.id, state.mode, step.id, state.number); - if (step.id !== state.step_id) { + if (state.number === 1) { Tour.log("Tour '"+state.id+"' Step: '" + (step._title || step.title) + "' (" + (new Date().getTime() - this.time) + "ms)"); } Tour.autoTogglePopover(true); - if (step.onload) { - step.onload(); + // onload a step you can fallback to an other step + if (step.onload && Tour._goto(step.onload())) { + return; } if (state.mode === "test") { diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 5767ffe5489..93ebc8b8167 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -302,6 +302,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM opacity: '1', filter: 'alpha(opacity = 100)' }); + instance.web.bus.trigger('form_view_shown', self); }); }, do_hide: function () { @@ -705,6 +706,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM if (menu) { menu.do_reload_needaction(); } + instance.web.bus.trigger('form_view_saved', self); }); }).always(function(){ $(e.target).attr("disabled", false); @@ -1835,7 +1837,6 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi trigger = trigger || this.$el; options = _.extend({ delay: { show: 500, hide: 0 }, - trigger: 'hover', title: function() { var template = widget.template + '.tooltip'; if (!QWeb.has_template(template)) { @@ -2577,10 +2578,10 @@ instance.web.form.FieldCharDomain = instance.web.form.AbstractField.extend(insta instance.web.DateTimeWidget = instance.web.Widget.extend({ template: "web.datepicker", - jqueryui_object: 'datetimepicker', type_of_date: "datetime", events: { - 'change .oe_datepicker_master': 'change_datetime', + 'dp.change .oe_datepicker_main': 'change_datetime', + 'dp.show .oe_datepicker_main': 'set_datetime_default', 'keypress .oe_datepicker_master': 'change_datetime', }, init: function(parent) { @@ -2589,82 +2590,32 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ }, start: function() { var self = this; + var l10n = _t.database.parameters; + var options = { + pickTime: true, + useSeconds: true, + startDate: new moment({ y: 1900 }), + endDate: new moment().add(200, "y"), + calendarWeeks: true, + icons : { + time: 'fa fa-clock-o', + date: 'fa fa-calendar', + up: 'fa fa-chevron-up', + down: 'fa fa-chevron-down' + }, + language : moment.locale(), + format : instance.web.convert_to_moment_format(l10n.date_format +' '+ l10n.time_format), + }; this.$input = this.$el.find('input.oe_datepicker_master'); - this.$input_picker = this.$el.find('input.oe_datepicker_container'); - - $.datepicker.setDefaults({ - clearText: _t('Clear'), - clearStatus: _t('Erase the current date'), - closeText: _t('Done'), - closeStatus: _t('Close without change'), - prevText: _t('<Prev'), - prevStatus: _t('Show the previous month'), - nextText: _t('Next>'), - nextStatus: _t('Show the next month'), - currentText: _t('Today'), - currentStatus: _t('Show the current month'), - monthNames: Date.CultureInfo.monthNames, - monthNamesShort: Date.CultureInfo.abbreviatedMonthNames, - monthStatus: _t('Show a different month'), - yearStatus: _t('Show a different year'), - weekHeader: _t('Wk'), - weekStatus: _t('Week of the year'), - dayNames: Date.CultureInfo.dayNames, - dayNamesShort: Date.CultureInfo.abbreviatedDayNames, - dayNamesMin: Date.CultureInfo.shortestDayNames, - dayStatus: _t('Set DD as first week day'), - dateStatus: _t('Select D, M d'), - firstDay: Date.CultureInfo.firstDayOfWeek, - initStatus: _t('Select a date'), - isRTL: false - }); - $.timepicker.setDefaults({ - timeOnlyTitle: _t('Choose Time'), - timeText: _t('Time'), - hourText: _t('Hour'), - minuteText: _t('Minute'), - secondText: _t('Second'), - currentText: _t('Now'), - closeText: _t('Done') - }); - - this.picker({ - onClose: this.on_picker_select, - onSelect: this.on_picker_select, - changeMonth: true, - changeYear: true, - showWeek: true, - showButtonPanel: true, - firstDay: Date.CultureInfo.firstDayOfWeek - }); - // Some clicks in the datepicker dialog are not stopped by the - // datepicker and "bubble through", unexpectedly triggering the bus's - // click event. Prevent that. - this.picker('widget').click(function (e) { e.stopPropagation(); }); - - this.$el.find('img.oe_datepicker_trigger').click(function() { - if (self.get("effective_readonly") || self.picker('widget').is(':visible')) { - self.$input.focus(); - return; - } - self.picker('setDate', self.get('value') ? instance.web.auto_str_to_date(self.get('value')) : new Date()); - self.$input_picker.show(); - self.picker('show'); - self.$input_picker.hide(); - }); + if (this.type_of_date === 'date') { + options['pickTime'] = false; + options['useSeconds'] = false; + options['format'] = instance.web.convert_to_moment_format(l10n.date_format); + } + this.picker = this.$('.oe_datepicker_main').datetimepicker(options); this.set_readonly(false); this.set({'value': false}); }, - picker: function() { - return $.fn[this.jqueryui_object].apply(this.$input_picker, arguments); - }, - on_picker_select: function(text, instance_) { - var date = this.picker('getDate'); - this.$input - .val(date ? this.format_client(date) : '') - .change() - .focus(); - }, set_value: function(value_) { this.set({'value': value_}); this.$input.val(value_ ? this.format_client(value_) : ''); @@ -2674,12 +2625,11 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ }, set_value_from_ui_: function() { var value_ = this.$input.val() || false; - this.set({'value': this.parse_client(value_)}); + this.set_value(this.parse_client(value_)); }, set_readonly: function(readonly) { this.readonly = readonly; this.$input.prop('readonly', this.readonly); - this.$el.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', readonly); }, is_valid_: function() { var value_ = this.$input.val(); @@ -2700,6 +2650,17 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ format_client: function(v) { return instance.web.format_value(v, {"widget": this.type_of_date}); }, + set_datetime_default: function(){ + //when opening datetimepicker the date and time by default should be the one from + //the input field if any or the current day otherwise + if (this.type_of_date === 'datetime') { + value = new moment().second(0); + if (this.$input.val().length !== 0 && this.is_valid_()){ + var value = this.$input.val(); + } + this.$('.oe_datepicker_main').data('DateTimePicker').setValue(value); + } + }, change_datetime: function(e) { if ((e.type !== "keypress" || e.which === 13) && this.is_valid_()) { this.set_value_from_ui_(); @@ -2712,7 +2673,6 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ }); instance.web.DateWidget = instance.web.DateTimeWidget.extend({ - jqueryui_object: 'datepicker', type_of_date: "date" }); @@ -3161,9 +3121,9 @@ instance.web.form.FieldRadio = instance.web.form.AbstractField.extend(instance.w this._super(field_manager, node); this.selection = _.clone(this.field.selection) || []; this.domain = false; + this.uniqueId = _.uniqueId("radio"); }, initialize_content: function () { - this.uniqueId = _.uniqueId("radio"); this.on("change:effective_readonly", this, this.render_value); this.field_manager.on("view_content_has_changed", this, this.get_selection); this.get_selection(); diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 9a192e4db90..fca5dd4f969 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -1623,6 +1623,7 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we self.setup_resequence_rows(list, dataset); }).always(function() { if (post_render) { post_render(); } + self.view.trigger('view_list_rendered'); }); }); return $el; diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 8a6c8def9ca..93ca3fe7b4d 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -344,6 +344,8 @@ instance.web.ActionManager = instance.web.Widget.extend({ }); } + instance.web.bus.trigger('action', action); + // Ensure context & domain are evaluated and can be manipulated/used var ncontext = new instance.web.CompoundContext(options.additional_context, action.context || {}); action.context = instance.web.pyeval.eval('context', ncontext); @@ -691,8 +693,8 @@ instance.web.ViewManager = instance.web.Widget.extend({ var container = this.$el.find("> div > div > .oe_view_manager_body > .oe_view_manager_view_" + view_type); var view_promise = controller.appendTo(container); this.views[view_type].controller = controller; - this.views[view_type].deferred.resolve(view_type); return $.when(view_promise).done(function() { + self.views[view_type].deferred.resolve(view_type); if (self.searchview && self.flags.auto_search && view.controller.searchable !== false) { @@ -725,6 +727,7 @@ instance.web.ViewManager = instance.web.Widget.extend({ } views.push(mode); } + instance.web.bus.trigger('view_switch_mode', self, mode); }); var item = _.extend({ widget: this, @@ -1122,7 +1125,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({ ); } - $.when(defs).done(function() { + $.when(this.views[this.active_view] ? this.views[this.active_view].deferred : $.when(), defs).done(function() { self.views[self.active_view].controller.do_load_state(state, warm); }); }, @@ -1481,6 +1484,7 @@ instance.web.View = instance.web.Widget.extend({ }, do_show: function () { this.$el.show(); + instance.web.bus.trigger('view_shown', this); }, do_hide: function () { this.$el.hide(); |
