Example #1
0
    QUnit.test('thread window\'s input can still be focused when the UI is blocked', function (assert) {
        assert.expect(2);

        var parent = this.createParent({
            data: this.data,
            services: this.services,
        });

        var $dom = $('#qunit-fixture');

        // get channel instance to link to thread window
        var channel = parent.call('mail_service', 'getChannel', 1);
        channel.detach();

        var $input = $('<input/>', {type: 'text'}).appendTo($dom);
        $input.focus().click();
        assert.strictEqual(document.activeElement, $input[0],
            "fake input should be focused");

        framework.blockUI();
        // cannot force focus here otherwise the test
        // makes no sense, this test is just about
        // making sure that the code which forces the
        // focus on click is not removed
        $('.o_thread_window .o_composer_text_field').click();
        assert.strictEqual(document.activeElement,
            $('.o_thread_window .o_composer_text_field')[0],
            "thread window's input should now be focused");

        framework.unblockUI();
        parent.destroy();
    });
Example #2
0
        return $.when(view_controller.do_show(view_options)).done(function () {
            // Prepare the ControlPanel content and update it
            var cp_status = {
                active_view_selector: '.o_cp_switch_' + self.active_view.type,
                breadcrumbs: self.action_manager && self.action_manager.get_breadcrumbs(),
                cp_content: _.extend({}, self.searchview_elements, view_control_elements),
                hidden: self.flags.headless,
                searchview: self.searchview,
                search_view_hidden: view_controller.searchable === false || view_controller.searchview_hidden,
            };
            self.update_control_panel(cp_status);

            // Detach the old view and store it
            if (old_view && old_view !== self.active_view) {
                // Store the scroll position
                if (self.action_manager && self.action_manager.webclient) {
                    old_view.controller.set_scrollTop(self.action_manager.webclient.get_scrollTop());
                }
                // Do not detach ui-autocomplete elements to let jquery-ui garbage-collect them
                var $to_detach = self.$el.contents().not('.ui-autocomplete');
                old_view.$fragment = framework.detach([{widget: old_view.controller}], {$to_detach: $to_detach});
            }

            // If the user switches from a multi-record to a mono-record view,
            // the action manager should be scrolled to the top.
            if (old_view && old_view.controller.multi_record === true && view_controller.multi_record === false) {
                view_controller.set_scrollTop(0);
            }

            // Append the view fragment to self.$el
            framework.append(self.$el, view_fragment, {
                in_DOM: self.is_in_DOM,
                callbacks: [{widget: view_controller}],
            });
        });
                (wkhtmltopdf_state = wkhtmltopdf_state || session.rpc('/report/check_wkhtmltopdf')).then(function (presence) {
                    // Fallback on html if wkhtmltopdf is not installed or if eCore is started with one worker
                    if (presence === 'install') {
                        self.do_notify(_t('Report'), _t('Unable to find Wkhtmltopdf on this \
system. The report will be shown in html.<br><br><a href="http://wkhtmltopdf.org/" target="_blank">\
wkhtmltopdf.org</a>'), true);
                        report_url = report_url.substring(12);
                        window.open('/report/html/' + report_url, '_blank', 'height=768,width=1024');
                        framework.unblockUI();
                        return;
                    } else if (presence === 'workers') {
                        self.do_notify(_t('Report'), _t('You need to start eCore with at least two \
workers to print a pdf version of the reports.'), true);
                        report_url = report_url.substring(12);
                        window.open('/report/html/' + report_url, '_blank', 'height=768,width=1024');
                        framework.unblockUI();
                        return;
                    } else if (presence === 'upgrade') {
                        self.do_notify(_t('Report'), _t('You should upgrade your version of\
Wkhtmltopdf to at least 0.12.0 in order to get a correct display of headers and footers as well as\
support for table-breaking between pages.<br><br><a href="http://wkhtmltopdf.org/" \
target="_blank">wkhtmltopdf.org</a>'), true);
                    }
                    return trigger_download(self.session, response, c, action, options);
                });
Example #4
0
            this.clear_uncommitted_changes().then(function() {
                // Save the current scroll position of the action_manager
                self.action_manager.set_scrollTop(self.get_scrollTop());

                // Detach the web_client contents and its navbar
                var $to_detach = self.$el.contents()
                        .not('.o_loading')
                        .not('.o_chat_window')
                        .not('.ui-autocomplete');
                self.$web_client_content = framework.detach([{widget: self.action_manager}], {$to_detach: $to_detach});
                framework.detach([{widget: self.menu}]);

                // Attach the app_switcher and its navbar
                framework.prepend(self.$el, [self.app_switcher_navbar.$el, self.app_switcher.$el], {
                    in_DOM: true,
                    callbacks: [{
                        widget: self.app_switcher_navbar,
                        callback_args: {
                            display_back_button: (self.action_manager.get_inner_action() !== null),
                        }
                    }],
                });

                // Save and clear the url
                self.url = $.bbq.getState();
                self._ignore_hashchange = true;
                $.bbq.removeState();
            });
Example #5
0
    QUnit.test('chat window\'s input can still be focused when the UI is blocked', function (assert) {
        assert.expect(2);

        function createParent(params) {
            var widget = new Widget();

            testUtils.addMockEnvironment(widget, params);
            return widget;
        }
        var parent = createParent({
            data: {},
            services: this.services,
        });

        var $dom = $('#qunit-fixture');

        var chatWindow = new ChatWindow(parent, 1, "user", false, [], {});
        chatWindow.appendTo($dom);
        var $input = $('<input/>', {type: 'text'}).appendTo($dom);
        $input.focus().click();
        assert.strictEqual(document.activeElement, $input[0],
            "fake input should be focused");

        framework.blockUI();
        chatWindow.$input.click(); // cannot force focus here otherwise the test
                                   // makes no sense, this test is just about
                                   // making sure that the code which forces the
                                   // focus on click is not removed
        assert.strictEqual(document.activeElement, chatWindow.$input[0],
            "chat window's input should now be focused");

        framework.unblockUI();
        parent.destroy();
    });
Example #6
0
 _downloadTable: function () {
     var table = this.model.exportData();
     if(table.measure_row.length + 1 > 256) {
         crash_manager.show_message(_t("For Excel compatibility, data cannot be exported if there are more than 256 columns.\n\nTip: try to flip axis, filter further or reduce the number of measures."));
         framework.unblockUI();
         return;
     }
     framework.blockUI();
     table.title = this.title;
     session.get_file({
         url: '/web/pivot/export_xls',
         data: {data: JSON.stringify(table)},
         complete: framework.unblockUI,
         error: crash_manager.rpc_error.bind(crash_manager)
     });
 },
Example #7
0
    on_click_export_data: function() {
        var self = this;
        var exported_fields = this.$el.find('#fields_list option').map(function () {
            // DOM property is textContent, but IE8 only knows innerText
            return {name: self.records[this.value] || this.value,
                    label: this.textContent || this.innerText};
        }).get();

        if (_.isEmpty(exported_fields)) {
            alert(_t("Please select fields to export..."));
            return;
        }
        exported_fields.unshift({name: 'id', label: 'External ID'});

        var export_format = this.$el.find("#export_format").val();

        framework.blockUI();
        this.session.get_file({
            url: '/web/export/' + export_format,
            data: {data: JSON.stringify({
                model: this.dataset.model,
                fields: exported_fields,
                ids: this.ids_to_export,
                domain: this.domain,
                context: pyeval.eval('contexts', [this.dataset._model.context()]),
                import_compat: !!this.$el.find("#import_compat").val(),
            })},
            complete: framework.unblockUI,
            error: crash_manager.rpc_error.bind(crash_manager),
        });
    },
Example #8
0
File: edi.js Project: 7Gates/odoo
 start: function() {
     if (!this.session.session_is_valid()) {
         framework.redirect('/web/login?redir=' + encodeURIComponent(window.location));
     } else {
         this.show_import();
     }
 },
Example #9
0
        return $.when(view_controller.do_show(view_options)).done(function () {
            // Prepare the ControlPanel content and update it
            var cp_status = {
                active_view_selector: '.oe-cp-switch-' + self.active_view.type,
                breadcrumbs: self.action_manager && self.action_manager.get_breadcrumbs(),
                cp_content: _.extend({}, self.control_elements, view_control_elements),
                hidden: self.flags.headless,
                searchview: self.searchview,
                search_view_hidden: view_controller.searchable === false || view_controller.searchview_hidden,
            };
            self.update_control_panel(cp_status);

            if (old_view) {
                // Detach the old view but not ui-autocomplete elements to let
                // jquery-ui garbage-collect them
                old_view.$container.contents().not('.ui-autocomplete').detach();

                // Hide old view (at first rendering, there is no view to hide)
                if (self.active_view !== old_view) {
                    if (old_view.controller) old_view.controller.do_hide();
                    if (old_view.$container) old_view.$container.hide();
                }
            }

            // Append the view fragment to its $container
            framework.append(self.active_view.$container, view_fragment, self.is_in_DOM);
        });
Example #10
0
 _downloadReport: function (url) {
     var self = this;
     framework.blockUI();
     return new Promise(function (resolve, reject) {
         var type = 'qweb-' + url.split('/')[2];
         var blocked = !session.get_file({
             url: '/report/download',
             data: {
                 data: JSON.stringify([url, type]),
             },
             success: resolve,
             error: function () {
                 crash_manager.rpc_error.apply(crash_manager, arguments);
                 reject();
             },
             complete: framework.unblockUI,
         });
         if (blocked) {
             // AAB: this check should be done in get_file service directly,
             // should not be the concern of the caller (and that way, get_file
             // could return a promise)
             var message = _t('A popup window with your report was blocked. You ' +
                              'may need to change your browser settings to allow ' +
                              'popup windows for this page.');
             self.do_warn(_t('Warning'), message, true);
         }
     });
 },
Example #11
0
 this.rpc("/web/database/create", {'fields': fields}).done(function(result) {
     if (result) {
         framework.redirect('/web');
     } else {
         alert("Failed to create database");
     }
 });
Example #12
0
    export_data: function() {
        var self = this;
        var exported_fields = this.$('.o_fields_list option').map(function () {
            return {
                name: (self.records[this.value] || this).value,
                label: this.textContent || this.innerText // DOM property is textContent, but IE8 only knows innerText
            };
        }).get();

        if (_.isEmpty(exported_fields)) {
            Dialog.alert(this, _t("Please select fields to export..."));
            return;
        }
        exported_fields.unshift({name: 'id', label: 'External ID'});

        var export_format = this.$export_format_inputs.filter(':checked').val();

        framework.blockUI();
        this.getSession().get_file({
            url: '/web/export/' + export_format,
            data: {data: JSON.stringify({
                model: this.record.model,
                fields: exported_fields,
                ids: this.ids_to_export,
                domain: this.domain,
                context: pyeval.eval('contexts', [this.record.getContext()]),
                import_compat: !!this.$import_compat_radios.filter(':checked').val(),
            })},
            complete: framework.unblockUI,
            error: crash_manager.rpc_error.bind(crash_manager),
        });
    },
Example #13
0
    on_rpc_event : function(increment) {
        var self = this;
        if (!this.count && increment === 1) {
            // Block UI after 3s
            this.long_running_timer = setTimeout(function () {
                self.blocked_ui = true;
                framework.blockUI();
            }, 3000);
        }

        this.count += increment;
        if (this.count > 0) {
            if (session.debug) {
                this.$el.text(_.str.sprintf( _t("Loading (%d)"), this.count));
            } else {
                this.$el.text(_t("Loading"));
            }
            this.$el.show();
            this.getParent().$el.addClass('oe_wait');
        } else {
            this.count = 0;
            clearTimeout(this.long_running_timer);
            // Don't unblock if blocked by somebody else
            if (self.blocked_ui) {
                this.blocked_ui = false;
                framework.unblockUI();
            }
            this.$el.fadeOut();
            this.getParent().$el.removeClass('oe_wait');
        }
    }
Example #14
0
 scrollTo: function (ev) {
     var offset = {top: ev.data.offset, left: ev.data.offset_left || 0};
     var xs_device = config.device.size_class <= config.device.SIZES.XS;
     if (!offset.top) {
         offset = framework.getPosition(document.querySelector(ev.data.selector));
         if (!xs_device) {
             // Substract the position of the action_manager as it is the scrolling part
             offset.top -= framework.getPosition(this.action_manager.el).top;
         }
     }
     if (xs_device) {
         this.el.scrollTop = offset.top;
     } else {
         this.action_manager.el.scrollTop = offset.top;
     }
     this.action_manager.el.scrollLeft = offset.left;
 },
Example #15
0
 .then(function(result) {
     if (self.messages_separator_position === 'top') {
         self.messages_separator_position = undefined; // reset value to re-compute separator position
     }
     self.thread.render(result, self.get_thread_rendering_options(result));
     offset += framework.getPosition(document.querySelector(oldest_msg_selector)).top;
     self.thread.scroll_to({offset: offset});
 });
Example #16
0
 ir_actions_act_url: function (action) {
     if (action.target === 'self') {
         framework.redirect(action.url);
     } else {
         window.open(action.url, '_blank');
     }
     return $.when();
 },
Example #17
0
 on_card_clicked: function(ev) {
     if (this.$el.find('.oe_kanban_global_click').size() > 0 && this.$el.find('.oe_kanban_global_click').data('routing')) {
         framework.redirect(this.$el.find('.oe_kanban_global_click').data('routing') + "/" + this.id);
     }
     else if (this.$el.find('.oe_kanban_global_click_edit').size()>0)
         this.do_action_edit();
     else
         this.do_action_open();
 },
Example #18
0
 ir_actions_act_url: function (action) {
     if (action.target === 'self') {
         framework.redirect(action.url);
         return $.Deferred(); // The action is finished only when the redirection is done
     } else {
         window.open(action.url, '_blank');
     }
     return $.when();
 },
Example #19
0
 on_card_clicked: function() {
     if (this.$el.hasClass('oe_kanban_global_click_edit') && this.$el.data('routing')) {
         framework.redirect(this.$el.data('routing') + "/" + this.id);
     } else if (this.$el.hasClass('oe_kanban_global_click_edit')) {
         this.trigger_up('kanban_record_edit', {id: this.id});
     } else {
         this.trigger_up('kanban_record_open', {id: this.id});
     }
 },
Example #20
0
 message_load_history: function() {
     var self = this;
     var oldest_msg_selector = '.o_mail_thread_message[data-message-id="' + this.get('messages')[0].id + '"]';
     var offset = -framework.getPosition(document.querySelector(oldest_msg_selector)).top;
     mail_thread.MailThreadMixin.message_load_history.call(this).then(function() {
         offset += framework.getPosition(document.querySelector(oldest_msg_selector)).top;
         self.$messages.scrollTop(offset);
     });
 },
Example #21
0
            return $.when(action.restore(index)).done(function() {
                if (action !== old_action) {
                    // Clear the action stack (this also removes the current action from the DOM)
                    self.clear_action_stack(to_destroy);

                    // Append the fragment of the action to restore to self.$el
                    framework.append(self.$el, action.get_fragment(), true);
                    self.inner_action.set_is_in_DOM(true);
                }
            });
Example #22
0
 load_more_messages: function () {
     var self = this;
     var top_msg_id = this.$('.o_thread_message').first().data('messageId');
     var top_msg_selector = '.o_thread_message[data-message-id="' + top_msg_id + '"]';
     var offset = -framework.getPosition(document.querySelector(top_msg_selector)).top;
     this.fetch_and_render_thread(this.msg_ids, {force_fetch: true}).then(function(){
         offset += framework.getPosition(document.querySelector(top_msg_selector)).top;
         self.thread.scroll_to({offset: offset});
     });
 },
Example #23
0
 on_attachment_changed: function(e) {
     var $e = $(e.target);
     if ($e.val() !== '') {
         this.$('form.o_form_binary_form').submit();
         $e.parent().find('input[type=file]').prop('disabled', true);
         $e.parent().find('button').prop('disabled', true).find('img, span').toggle();
         this.$('.o_sidebar_add_attachment a').text(_t('Uploading...'));
         framework.blockUI();
     }
 },
Example #24
0
    ir_actions_act_url: function (action) {
        var url = action.url;
        if (session.debug && url && url.length && url[0] === '/') {
            url = $.param.querystring(url, 'debug');
        }

        if (action.target === 'self') {
            framework.redirect(url);
        } else {
            window.open(url, '_blank');
        }
        return $.when();
    },
Example #25
0
            return $.when(action.restore(index)).done(function() {
                // Attach the DOM of the action and restore the scroll position only if necessary
                if (action !== old_action) {
                    // Clear the action stack (this also removes the current action from the DOM)
                    self.clear_action_stack(to_destroy);

                    // Append the fragment of the action to restore to self.$el
                    framework.append(self.$el, action.get_fragment(), {
                        in_DOM: self.is_in_DOM,
                        callbacks: [{widget: action.widget}],
                    });
                }
            });
Example #26
0
    ir_actions_report_xml: function(action, options) {
        var self = this;
        framework.blockUI();
        action = _.clone(action);
        var eval_contexts = ([session.user_context] || []).concat([action.context]);
        action.context = 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);
            framework.unblockUI();
            $('<a href="'+url+'" target="_blank"></a>')[0].click();
            return;
        }
        var c = crash_manager;
        return $.Deferred(function (d) {
            self.session.get_file({
                url: '/web/report',
                data: {action: JSON.stringify(action)},
                complete: framework.unblockUI,
                success: function(){
                    if (!self.dialog) {
                        options.on_close();
                    }
                    self.dialog_stop();
                    d.resolve();
                },
                error: function () {
                    c.rpc_error.apply(c, arguments);
                    d.reject();
                }
            });
        });
    },
Example #27
0
 P.call('get_param', ['database.uuid']).then(function(dbuuid) {
     var state = {
                 'd': session.db,
                 'u': window.location.protocol + '//' + window.location.host,
             };
     var params = {
         response_type: 'token',
         client_id: dbuuid || '',
         state: JSON.stringify(state),
         scope: 'userinfo',
     };
     framework.redirect('https://accounts.odoo.com/oauth2/auth?'+$.param(params));
 }).fail(function(result, ev){
Example #28
0
    ir_actions_act_url: function (action) {
        var url = action.url;
        if (session.debug && url && url.length && url[0] === '/') {
            url = $.param.querystring(url, {debug: session.debug});
        }

        if (action.target === 'self') {
            framework.redirect(url);
            return $.Deferred(); // The action is finished only when the redirection is done
        } else {
            window.open(url, '_blank');
        }
        return $.when();
    },
Example #29
0
 load_more_messages: function () {
     var self = this;
     var oldest_msg_id = this.$('.o_thread_message').first().data('messageId');
     var oldest_msg_selector = '.o_thread_message[data-message-id="' + oldest_msg_id + '"]';
     var offset = -framework.getPosition(document.querySelector(oldest_msg_selector)).top;
     return chat_manager
         .get_messages({channel_id: this.channel.id, domain: this.domain, load_more: true})
         .then(function(result) {
             if (self.messages_separator_position === 'top') {
                 self.messages_separator_position = undefined; // reset value to re-compute separator position
             }
             self.thread.render(result, self.get_thread_rendering_options(result));
             offset += framework.getPosition(document.querySelector(oldest_msg_selector)).top;
             self.thread.scroll_to({offset: offset});
         });
 },
Example #30
0
    _executeURLAction: function (action, options) {
        var url = action.url;
        if (config.debug && url && url.length && url[0] === '/') {
            url = $.param.querystring(url, {debug: config.debug});
        }

        if (action.target === 'self') {
            framework.redirect(url);
            return $.Deferred();
        } else {
            window.open(url, '_blank');
        }

        options.on_close();

        return $.when();
    },