diff --git a/addons/mail/static/src/js/thread_field.js b/addons/mail/static/src/js/thread_field.js index 218a4b552ec..2d809def129 100644 --- a/addons/mail/static/src/js/thread_field.js +++ b/addons/mail/static/src/js/thread_field.js @@ -112,7 +112,10 @@ var ThreadField = AbstractField.extend({ */ _fetchAndRenderThread: function (options) { var self = this; - if (!this._documentThread) { + if (!this._isMessagingReady) { + self._threadWidget.renderLoading(); + return Promise.resolve(); + } else if (!this._documentThread) { var thread = new CreateModeDocumentThread(); options = { isCreateMode: true }; self._threadWidget.render(thread, options); @@ -199,6 +202,7 @@ var ThreadField = AbstractField.extend({ return; } this._setDocumentThread(); + this._render(); }, /** * @private diff --git a/addons/mail/static/src/js/thread_widget.js b/addons/mail/static/src/js/thread_widget.js index 9550931ad95..3ec66d02520 100644 --- a/addons/mail/static/src/js/thread_widget.js +++ b/addons/mail/static/src/js/thread_widget.js @@ -55,6 +55,7 @@ var ThreadWidget = Widget.extend({ */ init: function (parent, options) { this._super.apply(this, arguments); + this.attachments = []; // options when the thread is enabled (e.g. can send message, // interact on messages, etc.) this._enabledOptions = _.defaults(options || {}, { @@ -220,6 +221,14 @@ var ThreadWidget = Widget.extend({ } }, + /** + * Render thread widget when loading, i.e. when messaging is not yet ready. + * @see /mail/init_messaging + */ + renderLoading: function () { + this.$el.html(QWeb.render('mail.widget.ThreadLoading')); + }, + //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- diff --git a/addons/mail/static/src/scss/thread.scss b/addons/mail/static/src/scss/thread.scss index ef220afa06c..c64b3f6aefd 100644 --- a/addons/mail/static/src/scss/thread.scss +++ b/addons/mail/static/src/scss/thread.scss @@ -1,3 +1,13 @@ +.o_mail_thread_loading { + display: flex; + align-items: center; + justify-content: center; +} + +.o_mail_thread_loading_icon { + margin-right: 5px; +} + .o_mail_thread, .o_mail_activity { .o_thread_show_more { text-align: center; diff --git a/addons/mail/static/src/xml/thread.xml b/addons/mail/static/src/xml/thread.xml index 24370c65e4e..31614cf4f4f 100644 --- a/addons/mail/static/src/xml/thread.xml +++ b/addons/mail/static/src/xml/thread.xml @@ -30,6 +30,12 @@ + +
+ + Please wait... +
+ diff --git a/addons/mail/static/tests/chatter_tests.js b/addons/mail/static/tests/chatter_tests.js index 02242f3ef2a..81742d8d2c2 100644 --- a/addons/mail/static/tests/chatter_tests.js +++ b/addons/mail/static/tests/chatter_tests.js @@ -203,6 +203,49 @@ QUnit.module('Chatter', { } }); +QUnit.test('messaging becomes ready', async function (assert) { + assert.expect(2); + + const initMessagingProm = testUtils.makeTestPromise(); + const form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + services: this.services, + arch: `
+ + + +
+ +
+
`, + async mockRPC(route, args) { + const _super = this._super.bind(this, route, args); // limitation on class.js with async/await + if (route === '/mail/init_messaging') { + await initMessagingProm; + } + return _super(); + }, + res_id: 2, + }); + await testUtils.nextTick(); + assert.containsOnce( + form, + '.o_mail_thread_loading', + "thread should be loading when messaging is not yet ready"); + + // simulate messaging becoming ready + initMessagingProm.resolve(); + await testUtils.nextTick(); + assert.containsNone( + form, + '.o_mail_thread_loading', + "thread should no longer be loading when messaging becomes ready"); + + form.destroy(); +}); + QUnit.test('basic rendering', async function (assert) { assert.expect(9);