@progress/kendo-angular-conversational-ui 21.0.0-develop.8 → 21.0.0-develop.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/chat/api/files-layout.d.ts +12 -0
  2. package/chat/api/index.d.ts +3 -1
  3. package/chat/api/message-settings.interface.d.ts +33 -0
  4. package/chat/api/message.interface.d.ts +5 -1
  5. package/chat/api/suggestions-layout.d.ts +20 -0
  6. package/chat/chat.component.d.ts +92 -34
  7. package/chat/chat.directives.d.ts +18 -0
  8. package/chat/chat.module.d.ts +15 -8
  9. package/chat/common/chat.service.d.ts +32 -3
  10. package/chat/common/models/model-fields.d.ts +0 -6
  11. package/chat/common/scroll-button.component.d.ts +32 -0
  12. package/chat/common/scroll.service.d.ts +39 -0
  13. package/chat/common/utils.d.ts +13 -1
  14. package/chat/l10n/messages.d.ts +9 -1
  15. package/chat/message-list.component.d.ts +20 -3
  16. package/chat/message.component.d.ts +40 -16
  17. package/chat/suggested-actions.component.d.ts +30 -5
  18. package/chat/templates/author-message-content-template.directive.d.ts +28 -0
  19. package/chat/templates/author-message-template.directive.d.ts +28 -0
  20. package/chat/templates/message-content-template.directive.d.ts +28 -0
  21. package/chat/templates/message-template.directive.d.ts +1 -1
  22. package/chat/templates/no-data-template.directive.d.ts +27 -0
  23. package/chat/templates/receiver-message-content-template.directive.d.ts +28 -0
  24. package/chat/templates/receiver-message-template.directive.d.ts +28 -0
  25. package/chat/templates/user-status-template.directive.d.ts +27 -0
  26. package/conversational-ui.module.d.ts +18 -11
  27. package/directives.d.ts +9 -2
  28. package/esm2022/chat/api/index.mjs +3 -1
  29. package/{chat/api/message-toolbar-visibility.d.ts → esm2022/chat/api/message-settings.interface.mjs} +1 -4
  30. package/esm2022/chat/api/suggestions-layout.mjs +5 -0
  31. package/esm2022/chat/builtin-actions.mjs +2 -0
  32. package/esm2022/chat/chat-file.component.mjs +2 -2
  33. package/esm2022/chat/chat.component.mjs +265 -71
  34. package/esm2022/chat/chat.directives.mjs +18 -0
  35. package/esm2022/chat/chat.module.mjs +16 -9
  36. package/esm2022/chat/common/chat.service.mjs +83 -4
  37. package/esm2022/chat/common/models/default-model-fields.mjs +0 -1
  38. package/esm2022/chat/common/scroll-button.component.mjs +81 -0
  39. package/esm2022/chat/common/scroll.service.mjs +110 -0
  40. package/esm2022/chat/common/utils.mjs +22 -3
  41. package/esm2022/chat/l10n/messages.mjs +13 -1
  42. package/esm2022/chat/message-attachments.component.mjs +2 -2
  43. package/esm2022/chat/message-box.component.mjs +5 -2
  44. package/esm2022/chat/message-list.component.mjs +165 -19
  45. package/esm2022/chat/message.component.mjs +487 -326
  46. package/esm2022/chat/suggested-actions.component.mjs +298 -80
  47. package/esm2022/chat/templates/author-message-content-template.directive.mjs +39 -0
  48. package/esm2022/chat/templates/author-message-template.directive.mjs +39 -0
  49. package/esm2022/chat/templates/message-content-template.directive.mjs +39 -0
  50. package/esm2022/chat/templates/message-template.directive.mjs +1 -1
  51. package/esm2022/chat/templates/no-data-template.directive.mjs +38 -0
  52. package/esm2022/chat/templates/receiver-message-content-template.directive.mjs +39 -0
  53. package/esm2022/chat/templates/receiver-message-template.directive.mjs +39 -0
  54. package/esm2022/chat/templates/user-status-template.directive.mjs +38 -0
  55. package/esm2022/conversational-ui.module.mjs +19 -12
  56. package/esm2022/directives.mjs +15 -1
  57. package/esm2022/index.mjs +7 -0
  58. package/esm2022/package-metadata.mjs +2 -2
  59. package/fesm2022/progress-kendo-angular-conversational-ui.mjs +1771 -547
  60. package/index.d.ts +7 -0
  61. package/package.json +14 -14
  62. /package/esm2022/chat/api/{message-toolbar-visibility.mjs → files-layout.mjs} +0 -0
@@ -6,7 +6,6 @@ import { Component, ContentChild, ElementRef, EventEmitter, HostBinding, Input,
6
6
  import { AttachmentTemplateDirective } from './templates/attachment-template.directive';
7
7
  import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n';
8
8
  import { makeHandler } from './builtin-actions';
9
- import { MessageTemplateDirective } from './templates/message-template.directive';
10
9
  import { Subscription } from 'rxjs';
11
10
  import { validatePackage } from '@progress/kendo-licensing';
12
11
  import { packageMetadata } from '../package-metadata';
@@ -24,11 +23,15 @@ import { KENDO_BUTTON } from '@progress/kendo-angular-buttons';
24
23
  import { pinIcon, xIcon } from '@progress/kendo-svg-icons';
25
24
  import { IconWrapperComponent } from '@progress/kendo-angular-icons';
26
25
  import { defaultModelFields } from './common/models/default-model-fields';
27
- import { processMessages, SEND_BTN_DEFAULT_SETTINGS, FILE_ACTIONS, CONTEXT_MENU_ACTIONS } from './common/utils';
26
+ import { processMessages, SEND_BTN_DEFAULT_SETTINGS, FILE_ACTIONS, CONTEXT_MENU_ACTIONS, transformActions, MENU_ITEM_SELECTOR } from './common/utils';
28
27
  import { ChatTimestampTemplateDirective } from './templates/timestamp-template.directive';
29
28
  import { MessageReferenceComponent } from './message-reference-content.component';
30
29
  import { ChatStatusTemplateDirective } from './templates/status-template.directive';
31
30
  import { ChatSuggestionTemplateDirective } from './templates/suggestion-template.directive';
31
+ import { ContextMenuComponent } from '@progress/kendo-angular-menu';
32
+ import { NoDataTemplateDirective, MessageTemplateDirective, AuthorMessageContentTemplateDirective, ReceiverMessageContentTemplateDirective, ReceiverMessageTemplateDirective, AuthorMessageTemplateDirective, MessageContentTemplateDirective } from './chat.directives';
33
+ import { ChatUserStatusTemplateDirective } from './templates/user-status-template.directive';
34
+ import { SuggestionsScrollService } from './common/scroll.service';
32
35
  import * as i0 from "@angular/core";
33
36
  import * as i1 from "@progress/kendo-angular-l10n";
34
37
  import * as i2 from "./common/chat.service";
@@ -50,7 +53,7 @@ import * as i3 from "@progress/kendo-angular-buttons";
50
53
  * ```
51
54
  *
52
55
  * @remarks
53
- * Supported children components are: {@link CustomMessagesComponent}, {@link HeroCardComponent}, {@link AttachmentTemplateDirective}, {@link ChatHeaderTemplateDirective}, {@link ChatMessageBoxTemplateDirective}, {@link MessageTemplateDirective}, {@link ChatStatusTemplateDirective}, {@link ChatSuggestionTemplateDirective}, {@link ChatTimestampTemplateDirective}.
56
+ * Supported children components are: {@link CustomMessagesComponent}, {@link HeroCardComponent}, {@link AttachmentTemplateDirective}, {@link ChatHeaderTemplateDirective}, {@link ChatMessageBoxTemplateDirective}, {@link MessageContentTemplateDirective}, {@link MessageTemplateDirective},{@link ChatStatusTemplateDirective}, {@link ChatSuggestionTemplateDirective}, {@link ChatTimestampTemplateDirective}, {@link ChatNoDataTemplateDirective}, {@link ChatUserStatusTemplateDirective}, {@link AuthorMessageContentTemplateDirective}, {@link ReceiverMessageContentTemplateDirective}, {@link ReceiverMessageTemplateDirective}, {@link AuthorMessageTemplateDirective}.
54
57
  */
55
58
  export class ChatComponent {
56
59
  localization;
@@ -59,13 +62,13 @@ export class ChatComponent {
59
62
  element;
60
63
  chatService;
61
64
  /**
62
- * Defines the array of messages displayed in the Chat.
63
- * Each message can include a timestamp for unique identification.
64
- * For more information, see [ngFor - Change Tracking](link:site.data.urls.angular['ngforof']#change-propagation).
65
+ * Sets the Chat messages.
66
+ * Accepts an array of `Message` objects, but can also accept custom data structures.
67
+ * For more information, check [Data Binding](slug:databinding_chat) section in the documentation.
65
68
  */
66
69
  messages;
67
70
  /**
68
- * Specifies the id representing the local user.
71
+ * Sets the ID that represents the local user.
69
72
  */
70
73
  authorId;
71
74
  /**
@@ -93,13 +96,14 @@ export class ChatComponent {
93
96
  */
94
97
  placeholder;
95
98
  /**
96
- * Switches the width of the message between the predefined options.
99
+ * Controls the width of the message between the predefined options.
97
100
  *
98
101
  * @default 'standard'
99
102
  */
100
103
  messageWidthMode = 'standard';
101
104
  /**
102
105
  * Enables the expand or collapse functionality for messages.
106
+ *
103
107
  * @default false
104
108
  */
105
109
  allowMessageCollapse = false;
@@ -116,24 +120,34 @@ export class ChatComponent {
116
120
  */
117
121
  enableFileSelect = true;
118
122
  /**
119
- * Specifies the actions available in the message toolbar.
123
+ * Sets the actions of the message toolbar.
120
124
  * These actions display in the message toolbar and let you perform specific operations on the message.
125
+ *
121
126
  * @default []
122
127
  */
123
128
  messageToolbarActions = [];
124
129
  /**
125
130
  * Sets the value of the Message Box.
131
+ *
126
132
  * @default ''
127
133
  */
128
134
  inputValue = '';
129
135
  /**
130
- * Specifies the default actions available in the message context menu.
136
+ * Sets the settings for the author's messages.
137
+ */
138
+ authorMessageSettings;
139
+ /**
140
+ * Sets the settings for the receivers' messages.
141
+ */
142
+ receiverMessageSettings;
143
+ /**
144
+ * Sets the default actions that display in the message context menu.
131
145
  *
132
146
  * @default [{ id: 'copy', label: 'Copy', icon: 'copy', svgIcon: copyIcon, disabled: false }, { id: 'reply', label: 'Reply', icon: 'undo', svgIcon: undoIcon, disabled: false }]
133
147
  */
134
148
  defaultContextMenuActions = CONTEXT_MENU_ACTIONS;
135
149
  /**
136
- * Specifies the actions available in the message as a context menu.
150
+ * Sets the actions that display in the message as a context menu.
137
151
  * These actions display as menu items and let you perform specific operations on the message.
138
152
  * The default actions are `copy` and `reply` and are defined by their `id`.
139
153
  */
@@ -144,11 +158,13 @@ export class ChatComponent {
144
158
  return this._messageContextMenuActions;
145
159
  }
146
160
  /**
147
- * Specifies the default actions available in the file actions DropDownButton.
161
+ * Sets the default actions that display in the file actions DropDownButton.
162
+ *
163
+ * @default [{ id: 'download', label: 'Download', icon: 'download', svgIcon: downloadIcon, disabled: false }]
148
164
  */
149
165
  defaultFileActions = FILE_ACTIONS;
150
166
  /**
151
- * Specifies the actions available in the file as items of a DropDownButton.
167
+ * Sets the actions that display in the file as items of a DropDownButton.
152
168
  * These actions display when you click the file DropDownButton and let you perform specific operations on the file.
153
169
  * The default action is `download` and is defined by its `id`.
154
170
  *
@@ -161,17 +177,40 @@ export class ChatComponent {
161
177
  return this._fileActions;
162
178
  }
163
179
  /**
164
- * Sets the suggestions to display in the message input box.
165
- * Suggestions display as a list of clickable items that let you quickly insert predefined text into the message input.
166
- * @default []
180
+ * Sets the layout of the files in the message bubble.
181
+ *
182
+ * @default 'vertical'
167
183
  */
168
- suggestions = [];
184
+ set messageFilesLayout(layout) {
185
+ this.chatService.messageFilesLayout = layout;
186
+ }
169
187
  /**
170
- * Sets the visibility of the message toolbar.
188
+ * Sets the layout of the suggestions above the message input box.
171
189
  *
172
- * @default 'hidden'
190
+ * @default 'scroll'
173
191
  */
174
- messageToolbarVisibility = 'hidden';
192
+ set suggestionsLayout(layoutMode) {
193
+ if (layoutMode) {
194
+ this.chatService.suggestionsLayout = layoutMode;
195
+ }
196
+ }
197
+ /**
198
+ * Sets the layout of the quick actions suggested below the messages.
199
+ *
200
+ * @default 'scroll'
201
+ */
202
+ set quickActionsLayout(layoutMode) {
203
+ if (layoutMode) {
204
+ this.chatService.quickActionsLayout = layoutMode;
205
+ }
206
+ }
207
+ /**
208
+ * Sets the suggestions that display in the message input box.
209
+ * Suggestions display as a list of clickable items that let you quickly insert predefined text into the message input.
210
+ *
211
+ * @default []
212
+ */
213
+ suggestions = [];
175
214
  /**
176
215
  * Sets the send button settings for the Chat component.
177
216
  * Allows customization of the send button appearance, icons and disabled state.
@@ -190,53 +229,53 @@ export class ChatComponent {
190
229
  return this._modelFields;
191
230
  }
192
231
  /**
193
- * Emits when the user sends a message by clicking the **Send** button or pressing **Enter**.
232
+ * Fires when the user sends a message by clicking the **Send** button or pressing **Enter**.
194
233
  *
195
234
  * The message is not automatically added to the `messages` array.
196
235
  */
197
236
  sendMessage = new EventEmitter();
198
237
  /**
199
- * Emits when the user clicks a quick action button in the message toolbar.
238
+ * Fires when the user clicks a quick action button in the message toolbar.
200
239
  */
201
240
  toolbarActionClick = new EventEmitter();
202
241
  /**
203
- * Emits when the user clicks an action in the message context menu.
242
+ * Fires when the user clicks an action in the message context menu.
204
243
  */
205
244
  contextMenuActionClick = new EventEmitter();
206
245
  /**
207
- * Emits when the user clicks an action in the file context menu.
246
+ * Fires when the user clicks an action in the file context menu.
208
247
  */
209
248
  fileActionClick = new EventEmitter();
210
249
  /**
211
- * Emits when the user clicks an action in the file context menu.
250
+ * Fires when the user clicks an action in the file context menu.
212
251
  */
213
252
  download = new EventEmitter();
214
253
  /**
215
- * Emits when the user clicks a quick action button.
254
+ * Fires when the user clicks a quick action button.
216
255
  * The Chat internally handles [known actions](slug:api_conversational-ui_actiontype) such as `reply`, `openUrl`, and `call`.
217
256
  *
218
257
  * The event is preventable. Calling [`preventDefault`](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault) suppresses the built-in action.
219
258
  */
220
259
  executeAction = new EventEmitter();
221
260
  /**
222
- * Emits when the user clicks a suggestion in the message input box.
261
+ * Fires when the user clicks a suggestion in the message input box.
223
262
  */
224
263
  suggestionExecute = new EventEmitter();
225
264
  /**
226
- * Emits when the user selects a file in the message input box.
265
+ * Fires when the user selects a file in the message input box.
227
266
  */
228
267
  fileSelect = new EventEmitter();
229
268
  /**
230
- * Emits when the user removes a file from the message input box.
269
+ * Fires when the user removes a file from the message input box.
231
270
  */
232
271
  fileRemove = new EventEmitter();
233
272
  /**
234
- * Emits when the user unpins the pinned message.
273
+ * Fires when the user unpins the pinned message.
235
274
  * This event triggers when the user clicks the delete button on the pinned message.
236
275
  */
237
276
  unpin = new EventEmitter();
238
277
  /**
239
- * Emits when the user types in the message input box.
278
+ * Fires when the user types in the message input box.
240
279
  */
241
280
  inputValueChange = new EventEmitter();
242
281
  get className() {
@@ -245,13 +284,23 @@ export class ChatComponent {
245
284
  get dirAttr() {
246
285
  return this.direction;
247
286
  }
287
+ set messagesContextMenu(contextMenu) {
288
+ this.chatService.messagesContextMenu = contextMenu;
289
+ }
248
290
  attachmentTemplate;
249
291
  chatHeaderTemplate;
292
+ chatNoDataTemplate;
293
+ authorMessageContentTemplate;
294
+ receiverMessageContentTemplate;
295
+ messageContentTemplate;
296
+ authorMessageTemplate;
297
+ receiverMessageTemplate;
250
298
  messageTemplate;
251
299
  timestampTemplate;
252
300
  suggestionTemplate;
253
301
  statusTemplate;
254
302
  messageBoxTemplate;
303
+ userStatusTemplate;
255
304
  messageBox;
256
305
  /**
257
306
  * @hidden
@@ -259,17 +308,30 @@ export class ChatComponent {
259
308
  messageList;
260
309
  /**
261
310
  * @hidden
262
- * Returns processed messages when model fields are used, otherwise returns original messages
311
+ * Returns processed messages when model fields are used, otherwise returns original messages.
263
312
  */
264
313
  get processedMessages() {
265
314
  if (!this.messages || this.messages.length === 0) {
266
315
  return [];
267
316
  }
268
317
  if (this._modelFields && Object.keys(this._modelFields).some(key => this._modelFields[key] !== defaultModelFields[key])) {
269
- return processMessages(this.messages, this._modelFields);
318
+ if (this.messages !== this._lastMessagesReference || this._modelFields !== this._lastModelFields) {
319
+ this._cachedProcessedMessages = processMessages(this.messages, this._modelFields);
320
+ this._lastMessagesReference = this.messages;
321
+ this._lastModelFields = this._modelFields;
322
+ }
323
+ return this._cachedProcessedMessages;
270
324
  }
271
325
  return this.messages;
272
326
  }
327
+ /**
328
+ * Gets the actions available in the message context menu.
329
+ *
330
+ * @hidden
331
+ */
332
+ get contextMenuActions() {
333
+ return transformActions(this.chatService.calculatedContextMenuActions);
334
+ }
273
335
  /**
274
336
  * @hidden
275
337
  */
@@ -297,6 +359,9 @@ export class ChatComponent {
297
359
  _modelFields = defaultModelFields;
298
360
  _messageContextMenuActions = CONTEXT_MENU_ACTIONS;
299
361
  _fileActions = FILE_ACTIONS;
362
+ _cachedProcessedMessages = [];
363
+ _lastMessagesReference = null;
364
+ _lastModelFields = null;
300
365
  constructor(localization, zone, renderer, element, chatService) {
301
366
  this.localization = localization;
302
367
  this.zone = zone;
@@ -321,7 +386,8 @@ export class ChatComponent {
321
386
  this.chatService.messageToolbarActions = this.messageToolbarActions;
322
387
  this.chatService.messageContextMenuActions = this.messageContextMenuActions;
323
388
  this.chatService.fileActions = this.fileActions;
324
- this.chatService.messageToolbarVisibility = this.messageToolbarVisibility;
389
+ this.chatService.authorMessageSettings = this.authorMessageSettings;
390
+ this.chatService.receiverMessageSettings = this.receiverMessageSettings;
325
391
  this.chatService.messages = this.processedMessages || [];
326
392
  this.chatService.chatElement = this.messageList;
327
393
  this.subs.add(this.chatService.toolbarAction$.subscribe((actionEvent) => {
@@ -369,7 +435,8 @@ export class ChatComponent {
369
435
  'messageToolbarActions',
370
436
  'messageContextMenuActions',
371
437
  'fileActions',
372
- 'messageToolbarVisibility'
438
+ 'authorMessageSettings',
439
+ 'receiverMessageSettings'
373
440
  ], changes);
374
441
  }
375
442
  /**
@@ -418,6 +485,43 @@ export class ChatComponent {
418
485
  this.chatService.scrollToMessage(this.pinnedMessage?.id);
419
486
  }
420
487
  }
488
+ /**
489
+ * @hidden
490
+ */
491
+ onContextMenuAction(action) {
492
+ if (action.id === 'reply') {
493
+ this.chatService.reply = this.chatService.activeMessage;
494
+ }
495
+ if (action.id === 'copy') {
496
+ navigator.clipboard.writeText(this.chatService.activeMessage.text);
497
+ }
498
+ this.chatService.emit('contextMenuAction', { action, message: this.chatService.activeMessage });
499
+ }
500
+ /**
501
+ * @hidden
502
+ */
503
+ handleMenuClose(event) {
504
+ if (event) {
505
+ const originalEvent = event.originalEvent;
506
+ originalEvent && this.onActionButtonClick(originalEvent);
507
+ }
508
+ this.chatService.activeMessage = null;
509
+ this.chatService.emit('contextMenuVisibilityChange', false);
510
+ if (this.chatService.selectOnMenuClose) {
511
+ this.chatService.activeMessageElement.selected = true;
512
+ this.chatService.focusActiveMessageElement();
513
+ }
514
+ }
515
+ /**
516
+ * @hidden
517
+ */
518
+ onActionButtonClick(event) {
519
+ const clickOutsideMessage = event instanceof MouseEvent && !event.target?.closest('.k-chat-bubble');
520
+ const menuItemClick = event instanceof MouseEvent && event.target?.closest(MENU_ITEM_SELECTOR);
521
+ if (clickOutsideMessage && !menuItemClick) {
522
+ this.chatService.selectOnMenuClose = false;
523
+ }
524
+ }
421
525
  findLastPinnedMessage() {
422
526
  return [...this.processedMessages].reverse().find((message) => message.isPinned);
423
527
  }
@@ -441,14 +545,15 @@ export class ChatComponent {
441
545
  });
442
546
  }
443
547
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatComponent, deps: [{ token: i1.LocalizationService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i2.ChatService }], target: i0.ɵɵFactoryTarget.Component });
444
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChatComponent, isStandalone: true, selector: "kendo-chat", inputs: { messages: "messages", authorId: "authorId", messageBoxType: "messageBoxType", height: "height", width: "width", placeholder: "placeholder", messageWidthMode: "messageWidthMode", allowMessageCollapse: "allowMessageCollapse", enableSpeechToText: "enableSpeechToText", enableFileSelect: "enableFileSelect", messageToolbarActions: "messageToolbarActions", inputValue: "inputValue", messageContextMenuActions: "messageContextMenuActions", fileActions: "fileActions", suggestions: "suggestions", messageToolbarVisibility: "messageToolbarVisibility", sendButtonSettings: "sendButtonSettings", modelFields: "modelFields" }, outputs: { sendMessage: "sendMessage", toolbarActionClick: "toolbarActionClick", contextMenuActionClick: "contextMenuActionClick", fileActionClick: "fileActionClick", download: "download", executeAction: "executeAction", suggestionExecute: "suggestionExecute", fileSelect: "fileSelect", fileRemove: "fileRemove", unpin: "unpin", inputValueChange: "inputValueChange" }, host: { properties: { "class": "this.className", "attr.dir": "this.dirAttr" } }, providers: [
548
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChatComponent, isStandalone: true, selector: "kendo-chat", inputs: { messages: "messages", authorId: "authorId", messageBoxType: "messageBoxType", height: "height", width: "width", placeholder: "placeholder", messageWidthMode: "messageWidthMode", allowMessageCollapse: "allowMessageCollapse", enableSpeechToText: "enableSpeechToText", enableFileSelect: "enableFileSelect", messageToolbarActions: "messageToolbarActions", inputValue: "inputValue", authorMessageSettings: "authorMessageSettings", receiverMessageSettings: "receiverMessageSettings", messageContextMenuActions: "messageContextMenuActions", fileActions: "fileActions", messageFilesLayout: "messageFilesLayout", suggestionsLayout: "suggestionsLayout", quickActionsLayout: "quickActionsLayout", suggestions: "suggestions", sendButtonSettings: "sendButtonSettings", modelFields: "modelFields" }, outputs: { sendMessage: "sendMessage", toolbarActionClick: "toolbarActionClick", contextMenuActionClick: "contextMenuActionClick", fileActionClick: "fileActionClick", download: "download", executeAction: "executeAction", suggestionExecute: "suggestionExecute", fileSelect: "fileSelect", fileRemove: "fileRemove", unpin: "unpin", inputValueChange: "inputValueChange" }, host: { properties: { "class": "this.className", "attr.dir": "this.dirAttr" } }, providers: [
445
549
  LocalizationService,
446
550
  ChatService,
551
+ SuggestionsScrollService,
447
552
  {
448
553
  provide: L10N_PREFIX,
449
554
  useValue: 'kendo.chat'
450
555
  }
451
- ], queries: [{ propertyName: "attachmentTemplate", first: true, predicate: AttachmentTemplateDirective, descendants: true }, { propertyName: "chatHeaderTemplate", first: true, predicate: ChatHeaderTemplateDirective, descendants: true }, { propertyName: "messageTemplate", first: true, predicate: MessageTemplateDirective, descendants: true }, { propertyName: "timestampTemplate", first: true, predicate: ChatTimestampTemplateDirective, descendants: true }, { propertyName: "suggestionTemplate", first: true, predicate: ChatSuggestionTemplateDirective, descendants: true }, { propertyName: "statusTemplate", first: true, predicate: ChatStatusTemplateDirective, descendants: true }, { propertyName: "messageBoxTemplate", first: true, predicate: ChatMessageBoxTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "messageBox", first: true, predicate: ["messageBox"], descendants: true }, { propertyName: "messageList", first: true, predicate: ["messageList"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `
556
+ ], queries: [{ propertyName: "attachmentTemplate", first: true, predicate: AttachmentTemplateDirective, descendants: true }, { propertyName: "chatHeaderTemplate", first: true, predicate: ChatHeaderTemplateDirective, descendants: true }, { propertyName: "chatNoDataTemplate", first: true, predicate: NoDataTemplateDirective, descendants: true }, { propertyName: "authorMessageContentTemplate", first: true, predicate: AuthorMessageContentTemplateDirective, descendants: true }, { propertyName: "receiverMessageContentTemplate", first: true, predicate: ReceiverMessageContentTemplateDirective, descendants: true }, { propertyName: "messageContentTemplate", first: true, predicate: MessageContentTemplateDirective, descendants: true }, { propertyName: "authorMessageTemplate", first: true, predicate: AuthorMessageTemplateDirective, descendants: true }, { propertyName: "receiverMessageTemplate", first: true, predicate: ReceiverMessageTemplateDirective, descendants: true }, { propertyName: "messageTemplate", first: true, predicate: MessageTemplateDirective, descendants: true }, { propertyName: "timestampTemplate", first: true, predicate: ChatTimestampTemplateDirective, descendants: true }, { propertyName: "suggestionTemplate", first: true, predicate: ChatSuggestionTemplateDirective, descendants: true }, { propertyName: "statusTemplate", first: true, predicate: ChatStatusTemplateDirective, descendants: true }, { propertyName: "messageBoxTemplate", first: true, predicate: ChatMessageBoxTemplateDirective, descendants: true }, { propertyName: "userStatusTemplate", first: true, predicate: ChatUserStatusTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "messagesContextMenu", first: true, predicate: ["messagesContextMenu"], descendants: true }, { propertyName: "messageBox", first: true, predicate: ["messageBox"], descendants: true }, { propertyName: "messageList", first: true, predicate: ["messageList"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `
452
557
  <ng-container kendoChatLocalizedMessages
453
558
  i18n-deletedMessageSenderText="kendo.chat.deletedMessageSenderText|The text that is displayed when the sender deletes a message"
454
559
  deletedMessageSenderText="You removed this message."
@@ -497,10 +602,16 @@ export class ChatComponent {
497
602
 
498
603
  i18n-downloadAllFilesText="kendo.chat.downloadAllFilesText|Sets the text that is displayed in the download section of the message."
499
604
  downloadAllFilesText="Download all"
605
+
606
+ i18n-previousSuggestionsButtonTitle="kendo.chat.previousSuggestionsButtonTitle|The title of the button that scrolls to the previous suggestions"
607
+ previousSuggestionsButtonTitle="Scroll left"
608
+
609
+ i18n-nextSuggestionsButtonTitle="kendo.chat.nextSuggestionsButtonTitle|The title of the button that scrolls to the next suggestions"
610
+ nextSuggestionsButtonTitle="Scroll right"
500
611
  >
501
612
  </ng-container>
502
613
 
503
- <kendo-appbar *ngIf="chatHeaderTemplate" class="k-chat-header" positionMode="sticky">
614
+ <kendo-appbar *ngIf="chatHeaderTemplate" class="k-chat-header" positionMode="sticky" themeColor="inherit">
504
615
  <ng-container *ngTemplateOutlet="chatHeaderTemplate.templateRef"></ng-container>
505
616
  </kendo-appbar>
506
617
  <div class="k-message-reference k-message-reference-receiver k-message-pinned" *ngIf="pinnedMessage" (click)="scrollToPinnedMessage()">
@@ -516,7 +627,7 @@ export class ChatComponent {
516
627
  </div>
517
628
  <div
518
629
  #messageList
519
- class="k-message-list k-avatars"
630
+ class="k-message-list"
520
631
  aria-live="polite"
521
632
  role="log"
522
633
  kendoChatScrollAnchor
@@ -524,19 +635,32 @@ export class ChatComponent {
524
635
  #anchor="scrollAnchor"
525
636
  [(autoScroll)]="autoScroll"
526
637
  >
527
- <kendo-chat-message-list
528
- [messages]="processedMessages"
529
- [messageTemplate]="messageTemplate"
530
- [timestampTemplate]="timestampTemplate"
531
- [statusTemplate]="statusTemplate"
532
- [localization]="localizationText"
533
- [attachmentTemplate]="attachmentTemplate"
534
- [authorId]="authorId"
535
- (executeAction)="dispatchAction($event)"
536
- (resize)="anchor.scrollToBottom()"
537
- (navigate)="this.autoScroll = false"
538
- >
539
- </kendo-chat-message-list>
638
+ <div *ngIf="processedMessages && processedMessages.length === 0; else chatMessageList" class="k-message-list-content k-message-list-content-empty">
639
+ <ng-template
640
+ [ngTemplateOutlet]="chatNoDataTemplate?.templateRef">
641
+ </ng-template>
642
+ </div>
643
+ <ng-template #chatMessageList>
644
+ <kendo-chat-message-list
645
+ [messages]="processedMessages"
646
+ [authorMessageContentTemplate]="authorMessageContentTemplate"
647
+ [receiverMessageContentTemplate]="receiverMessageContentTemplate"
648
+ [messageContentTemplate]="messageContentTemplate"
649
+ [authorMessageTemplate]="authorMessageTemplate"
650
+ [receiverMessageTemplate]="receiverMessageTemplate"
651
+ [messageTemplate]="messageTemplate"
652
+ [timestampTemplate]="timestampTemplate"
653
+ [statusTemplate]="statusTemplate"
654
+ [userStatusTemplate]="userStatusTemplate"
655
+ [localization]="localizationText"
656
+ [attachmentTemplate]="attachmentTemplate"
657
+ [authorId]="authorId"
658
+ (executeAction)="dispatchAction($event)"
659
+ (resize)="anchor.scrollToBottom()"
660
+ (navigate)="this.autoScroll = false"
661
+ >
662
+ </kendo-chat-message-list>
663
+ </ng-template>
540
664
  </div>
541
665
  <kendo-message-box
542
666
  #messageBox
@@ -554,7 +678,16 @@ export class ChatComponent {
554
678
  (fileRemove)="fileRemove.emit($event)"
555
679
  >
556
680
  </kendo-message-box>
557
- `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoChatLocalizedMessages]" }, { kind: "directive", type: ScrollAnchorDirective, selector: "[kendoChatScrollAnchor]", inputs: ["autoScroll"], outputs: ["autoScrollChange"], exportAs: ["scrollAnchor"] }, { kind: "component", type: MessageListComponent, selector: "kendo-chat-message-list", inputs: ["messages", "attachmentTemplate", "messageTemplate", "timestampTemplate", "statusTemplate", "localization", "authorId"], outputs: ["executeAction", "navigate", "resize"] }, { kind: "component", type: MessageBoxComponent, selector: "kendo-message-box", inputs: ["authorId", "autoScroll", "suggestions", "placeholder", "inputValue", "localization", "messageBoxTemplate", "suggestionTemplate"], outputs: ["sendMessage", "executeSuggestion", "fileSelect", "fileRemove"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }, { kind: "component", type: AppBarComponent, selector: "kendo-appbar", inputs: ["position", "positionMode", "themeColor"], exportAs: ["kendoAppBar"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: i3.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
681
+
682
+ <kendo-contextmenu
683
+ #messagesContextMenu
684
+ [items]="contextMenuActions"
685
+ [popupAlign]="{ horizontal: 'right', vertical: 'top' }"
686
+ [collision]="{ horizontal: 'flip', vertical: 'flip'}"
687
+ (popupClose)="handleMenuClose($event)"
688
+ (select)="onContextMenuAction($event.item.originalAction)"
689
+ ></kendo-contextmenu>
690
+ `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoChatLocalizedMessages]" }, { kind: "directive", type: ScrollAnchorDirective, selector: "[kendoChatScrollAnchor]", inputs: ["autoScroll"], outputs: ["autoScrollChange"], exportAs: ["scrollAnchor"] }, { kind: "component", type: MessageListComponent, selector: "kendo-chat-message-list", inputs: ["messages", "attachmentTemplate", "authorMessageContentTemplate", "receiverMessageContentTemplate", "messageContentTemplate", "authorMessageTemplate", "receiverMessageTemplate", "messageTemplate", "timestampTemplate", "statusTemplate", "userStatusTemplate", "localization", "authorId"], outputs: ["executeAction", "navigate", "resize"] }, { kind: "component", type: MessageBoxComponent, selector: "kendo-message-box", inputs: ["authorId", "autoScroll", "suggestions", "placeholder", "inputValue", "localization", "messageBoxTemplate", "suggestionTemplate"], outputs: ["sendMessage", "executeSuggestion", "fileSelect", "fileRemove"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }, { kind: "component", type: AppBarComponent, selector: "kendo-appbar", inputs: ["position", "positionMode", "themeColor"], exportAs: ["kendoAppBar"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: i3.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: ContextMenuComponent, selector: "kendo-contextmenu", inputs: ["showOn", "target", "filter", "alignToAnchor", "vertical", "popupAnimate", "popupAlign", "anchorAlign", "collision", "appendTo", "ariaLabel"], outputs: ["popupOpen", "popupClose", "select", "open", "close"], exportAs: ["kendoContextMenu"] }] });
558
691
  }
559
692
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatComponent, decorators: [{
560
693
  type: Component,
@@ -562,6 +695,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
562
695
  providers: [
563
696
  LocalizationService,
564
697
  ChatService,
698
+ SuggestionsScrollService,
565
699
  {
566
700
  provide: L10N_PREFIX,
567
701
  useValue: 'kendo.chat'
@@ -617,10 +751,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
617
751
 
618
752
  i18n-downloadAllFilesText="kendo.chat.downloadAllFilesText|Sets the text that is displayed in the download section of the message."
619
753
  downloadAllFilesText="Download all"
754
+
755
+ i18n-previousSuggestionsButtonTitle="kendo.chat.previousSuggestionsButtonTitle|The title of the button that scrolls to the previous suggestions"
756
+ previousSuggestionsButtonTitle="Scroll left"
757
+
758
+ i18n-nextSuggestionsButtonTitle="kendo.chat.nextSuggestionsButtonTitle|The title of the button that scrolls to the next suggestions"
759
+ nextSuggestionsButtonTitle="Scroll right"
620
760
  >
621
761
  </ng-container>
622
762
 
623
- <kendo-appbar *ngIf="chatHeaderTemplate" class="k-chat-header" positionMode="sticky">
763
+ <kendo-appbar *ngIf="chatHeaderTemplate" class="k-chat-header" positionMode="sticky" themeColor="inherit">
624
764
  <ng-container *ngTemplateOutlet="chatHeaderTemplate.templateRef"></ng-container>
625
765
  </kendo-appbar>
626
766
  <div class="k-message-reference k-message-reference-receiver k-message-pinned" *ngIf="pinnedMessage" (click)="scrollToPinnedMessage()">
@@ -636,7 +776,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
636
776
  </div>
637
777
  <div
638
778
  #messageList
639
- class="k-message-list k-avatars"
779
+ class="k-message-list"
640
780
  aria-live="polite"
641
781
  role="log"
642
782
  kendoChatScrollAnchor
@@ -644,19 +784,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
644
784
  #anchor="scrollAnchor"
645
785
  [(autoScroll)]="autoScroll"
646
786
  >
647
- <kendo-chat-message-list
648
- [messages]="processedMessages"
649
- [messageTemplate]="messageTemplate"
650
- [timestampTemplate]="timestampTemplate"
651
- [statusTemplate]="statusTemplate"
652
- [localization]="localizationText"
653
- [attachmentTemplate]="attachmentTemplate"
654
- [authorId]="authorId"
655
- (executeAction)="dispatchAction($event)"
656
- (resize)="anchor.scrollToBottom()"
657
- (navigate)="this.autoScroll = false"
658
- >
659
- </kendo-chat-message-list>
787
+ <div *ngIf="processedMessages && processedMessages.length === 0; else chatMessageList" class="k-message-list-content k-message-list-content-empty">
788
+ <ng-template
789
+ [ngTemplateOutlet]="chatNoDataTemplate?.templateRef">
790
+ </ng-template>
791
+ </div>
792
+ <ng-template #chatMessageList>
793
+ <kendo-chat-message-list
794
+ [messages]="processedMessages"
795
+ [authorMessageContentTemplate]="authorMessageContentTemplate"
796
+ [receiverMessageContentTemplate]="receiverMessageContentTemplate"
797
+ [messageContentTemplate]="messageContentTemplate"
798
+ [authorMessageTemplate]="authorMessageTemplate"
799
+ [receiverMessageTemplate]="receiverMessageTemplate"
800
+ [messageTemplate]="messageTemplate"
801
+ [timestampTemplate]="timestampTemplate"
802
+ [statusTemplate]="statusTemplate"
803
+ [userStatusTemplate]="userStatusTemplate"
804
+ [localization]="localizationText"
805
+ [attachmentTemplate]="attachmentTemplate"
806
+ [authorId]="authorId"
807
+ (executeAction)="dispatchAction($event)"
808
+ (resize)="anchor.scrollToBottom()"
809
+ (navigate)="this.autoScroll = false"
810
+ >
811
+ </kendo-chat-message-list>
812
+ </ng-template>
660
813
  </div>
661
814
  <kendo-message-box
662
815
  #messageBox
@@ -674,9 +827,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
674
827
  (fileRemove)="fileRemove.emit($event)"
675
828
  >
676
829
  </kendo-message-box>
830
+
831
+ <kendo-contextmenu
832
+ #messagesContextMenu
833
+ [items]="contextMenuActions"
834
+ [popupAlign]="{ horizontal: 'right', vertical: 'top' }"
835
+ [collision]="{ horizontal: 'flip', vertical: 'flip'}"
836
+ (popupClose)="handleMenuClose($event)"
837
+ (select)="onContextMenuAction($event.item.originalAction)"
838
+ ></kendo-contextmenu>
677
839
  `,
678
840
  standalone: true,
679
- imports: [LocalizedMessagesDirective, ScrollAnchorDirective, MessageListComponent, MessageBoxComponent, MessageReferenceComponent, AppBarComponent, NgTemplateOutlet, NgIf, IconWrapperComponent, KENDO_BUTTON]
841
+ imports: [LocalizedMessagesDirective, ScrollAnchorDirective, MessageListComponent, MessageBoxComponent, MessageReferenceComponent, AppBarComponent, NgTemplateOutlet, NgIf, IconWrapperComponent, KENDO_BUTTON, ContextMenuComponent]
680
842
  }]
681
843
  }], ctorParameters: () => [{ type: i1.LocalizationService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i2.ChatService }], propDecorators: { messages: [{
682
844
  type: Input
@@ -702,13 +864,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
702
864
  type: Input
703
865
  }], inputValue: [{
704
866
  type: Input
867
+ }], authorMessageSettings: [{
868
+ type: Input
869
+ }], receiverMessageSettings: [{
870
+ type: Input
705
871
  }], messageContextMenuActions: [{
706
872
  type: Input
707
873
  }], fileActions: [{
708
874
  type: Input
709
- }], suggestions: [{
875
+ }], messageFilesLayout: [{
876
+ type: Input
877
+ }], suggestionsLayout: [{
878
+ type: Input
879
+ }], quickActionsLayout: [{
710
880
  type: Input
711
- }], messageToolbarVisibility: [{
881
+ }], suggestions: [{
712
882
  type: Input
713
883
  }], sendButtonSettings: [{
714
884
  type: Input
@@ -742,12 +912,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
742
912
  }], dirAttr: [{
743
913
  type: HostBinding,
744
914
  args: ['attr.dir']
915
+ }], messagesContextMenu: [{
916
+ type: ViewChild,
917
+ args: ['messagesContextMenu']
745
918
  }], attachmentTemplate: [{
746
919
  type: ContentChild,
747
920
  args: [AttachmentTemplateDirective]
748
921
  }], chatHeaderTemplate: [{
749
922
  type: ContentChild,
750
923
  args: [ChatHeaderTemplateDirective]
924
+ }], chatNoDataTemplate: [{
925
+ type: ContentChild,
926
+ args: [NoDataTemplateDirective]
927
+ }], authorMessageContentTemplate: [{
928
+ type: ContentChild,
929
+ args: [AuthorMessageContentTemplateDirective]
930
+ }], receiverMessageContentTemplate: [{
931
+ type: ContentChild,
932
+ args: [ReceiverMessageContentTemplateDirective]
933
+ }], messageContentTemplate: [{
934
+ type: ContentChild,
935
+ args: [MessageContentTemplateDirective]
936
+ }], authorMessageTemplate: [{
937
+ type: ContentChild,
938
+ args: [AuthorMessageTemplateDirective]
939
+ }], receiverMessageTemplate: [{
940
+ type: ContentChild,
941
+ args: [ReceiverMessageTemplateDirective]
751
942
  }], messageTemplate: [{
752
943
  type: ContentChild,
753
944
  args: [MessageTemplateDirective]
@@ -763,6 +954,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
763
954
  }], messageBoxTemplate: [{
764
955
  type: ContentChild,
765
956
  args: [ChatMessageBoxTemplateDirective]
957
+ }], userStatusTemplate: [{
958
+ type: ContentChild,
959
+ args: [ChatUserStatusTemplateDirective]
766
960
  }], messageBox: [{
767
961
  type: ViewChild,
768
962
  args: ['messageBox']