diff --git a/packages/devextreme/js/__internal/ui/chat/chat_message_list.ts b/packages/devextreme/js/__internal/ui/chat/chat_message_list.ts index de538aab406f..dfa9ada27a7f 100644 --- a/packages/devextreme/js/__internal/ui/chat/chat_message_list.ts +++ b/packages/devextreme/js/__internal/ui/chat/chat_message_list.ts @@ -22,7 +22,7 @@ class MessageList extends Widget { private _$content!: dxElementWrapper; - private _scrollable!: Scrollable; + private _scrollable?: Scrollable; _getDefaultOptions(): MessageListOptions { return { @@ -60,7 +60,8 @@ class MessageList extends Widget { } _createMessageGroupComponent(items: Message[], userId: string | number | undefined): void { - const $messageGroup = $('
').appendTo(this._$content); + const $messageGroupContainer = this._scrollable ? this._scrollable.content() : this._$content; + const $messageGroup = $('
').appendTo($messageGroupContainer); const messageGroup = this._createComponent($messageGroup, MessageGroup, { items, @@ -141,11 +142,12 @@ class MessageList extends Widget { const lastMessageGroup = this._messageGroups[this._messageGroups.length - 1]; const element = lastMessageGroup.$element()[0]; - this._scrollable.scrollToElement(element); + this._scrollable?.scrollToElement(element); } _clean(): void { this._messageGroups = []; + this._scrollable = undefined; super._clean(); } diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/chat.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/chat.tests.js index a33258e6e858..368f1e9454ee 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/chat.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/chat.tests.js @@ -297,7 +297,7 @@ QUnit.module('Chat', moduleConfig, () => { assert.strictEqual(lastItem, newMessage); }); - QUnit.test('Message Group should be created if items are empty', function(assert) { + QUnit.test('Message Group should be created if items was empty', function(assert) { this.instance.option({ items: [] }); const author = { diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/messageList.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/messageList.tests.js index 03ea8f126da7..b2a8dcd963d3 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/messageList.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets/chatParts/messageList.tests.js @@ -3,8 +3,11 @@ import $ from 'jquery'; import MessageList from '__internal/ui/chat/chat_message_list'; import Scrollable from 'ui/scroll_view/ui.scrollable'; import { - generateMessages, userFirst, userSecond, - NOW, MOCK_COMPANION_USER_ID, MOCK_CURRENT_USER_ID + generateMessages, + userFirst, + NOW, + MOCK_COMPANION_USER_ID, + MOCK_CURRENT_USER_ID, } from './chat.tests.js'; import MessageGroup from '__internal/ui/chat/chat_message_group'; @@ -22,7 +25,9 @@ const moduleConfig = { this.instance = new MessageList($('#messageList'), options); this.$element = $(this.instance.$element()); - this.scrollable = Scrollable.getInstance(this.$element.find(`.${SCROLLABLE_CLASS}`)); + this.getScrollable = () => Scrollable.getInstance(this.$element.find(`.${SCROLLABLE_CLASS}`)); + + this.scrollable = this.getScrollable(); }; this.reinit = (options) => { @@ -60,6 +65,61 @@ QUnit.module('MessageList', moduleConfig, () => { QUnit.test('scrollable should be rendered inside root element', function(assert) { assert.ok(Scrollable.getInstance(this.$element.children().first()) instanceof Scrollable); }); + + QUnit.test('Message Group should be rendered in the scrollable content', function(assert) { + const newMessage = { + author: { id: MOCK_CURRENT_USER_ID }, + timestamp: NOW, + text: 'NEW MESSAGE', + }; + + this.reinit({ items: [newMessage] }); + + const $messageGroups = $(this.scrollable.content()).find(`.${CHAT_MESSAGE_GROUP_CLASS}`); + + assert.strictEqual($messageGroups.length, 1); + }); + + QUnit.test('Message Group should be rendered in the scrollable content after adding 1 new message', function(assert) { + const newMessage = { + author: { id: MOCK_CURRENT_USER_ID }, + timestamp: NOW, + text: 'NEW MESSAGE', + }; + + this.instance.option({ items: [newMessage] }); + + const $messageGroups = $(this.scrollable.content()).find(`.${CHAT_MESSAGE_GROUP_CLASS}`); + + assert.strictEqual($messageGroups.length, 1); + }); + + QUnit.test('Message Group should be rendered in the scrollable content after adding 1 new message to items', function(assert) { + const items = generateMessages(52); + + this.reinit({ items }); + + const newMessage = { + author: { id: 'another user' }, + timestamp: NOW, + text: 'NEW MESSAGE', + }; + + this.instance.option({ items: [...items, newMessage] }); + + const $messageGroups = $(this.scrollable.content()).find(`.${CHAT_MESSAGE_GROUP_CLASS}`); + + assert.strictEqual($messageGroups.length, 27); + }); + + QUnit.test('Message Group should be rendered in the scrollable content after updating items at runtime', function(assert) { + this.instance.option({ items: generateMessages(52) }); + + const scrollableContent = this.getScrollable().content(); + const $messageGroups = $(scrollableContent).find(`.${CHAT_MESSAGE_GROUP_CLASS}`); + + assert.strictEqual($messageGroups.length, 26); + }); }); QUnit.module('MessageGroup integration', () => {