@progress/kendo-angular-conversational-ui 20.0.0-develop.4 → 20.0.0-develop.6

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 (86) hide show
  1. package/chat/api/action.interface.d.ts +1 -1
  2. package/chat/api/attachment.interface.d.ts +1 -1
  3. package/chat/api/chat-file-interface.d.ts +41 -0
  4. package/chat/api/chat-suggestion.interface.d.ts +25 -0
  5. package/chat/api/file-action.d.ts +42 -0
  6. package/chat/api/file-download-event.interface.d.ts +21 -0
  7. package/chat/api/index.d.ts +8 -0
  8. package/chat/api/message-action.d.ts +42 -0
  9. package/{esm2022/chat/chat.directives.mjs → chat/api/message-toolbar-visibility.d.ts} +4 -4
  10. package/chat/api/message-width-mode.d.ts +10 -0
  11. package/chat/api/message.interface.d.ts +30 -12
  12. package/chat/api/send-button-settings.d.ts +15 -0
  13. package/chat/api/user.interface.d.ts +4 -0
  14. package/chat/attachment.component.d.ts +1 -1
  15. package/chat/cards/hero-card.component.d.ts +1 -1
  16. package/chat/chat-file.component.d.ts +34 -0
  17. package/chat/chat-item.d.ts +1 -0
  18. package/chat/chat-view.d.ts +1 -1
  19. package/chat/chat.component.d.ts +218 -19
  20. package/chat/chat.module.d.ts +8 -4
  21. package/chat/common/chat.service.d.ts +51 -0
  22. package/chat/{chat.directives.d.ts → common/models/default-model-fields.d.ts} +5 -4
  23. package/chat/common/models/message-box-options.d.ts +1 -1
  24. package/chat/common/models/model-fields.d.ts +111 -0
  25. package/chat/common/utils.d.ts +50 -0
  26. package/chat/l10n/messages.d.ts +40 -3
  27. package/chat/message-attachments.component.d.ts +1 -4
  28. package/chat/message-box.component.d.ts +54 -25
  29. package/chat/message-list.component.d.ts +18 -11
  30. package/chat/message-reference-content.component.d.ts +24 -0
  31. package/chat/message.component.d.ts +54 -6
  32. package/chat/suggested-actions.component.d.ts +17 -4
  33. package/chat/templates/header-template.directive.d.ts +24 -0
  34. package/chat/{message-box.directive.d.ts → templates/message-box.directive.d.ts} +1 -1
  35. package/chat/templates/status-template.directive.d.ts +24 -0
  36. package/chat/templates/suggestion-template.directive.d.ts +24 -0
  37. package/chat/templates/timestamp-template.directive.d.ts +28 -0
  38. package/codemods/template-transformer/index.js +94 -0
  39. package/codemods/utils.js +609 -0
  40. package/codemods/v20/chat-user.js +50 -0
  41. package/conversational-ui.module.d.ts +11 -7
  42. package/directives.d.ts +9 -5
  43. package/esm2022/chat/api/chat-file-interface.mjs +5 -0
  44. package/esm2022/chat/api/chat-suggestion.interface.mjs +5 -0
  45. package/esm2022/chat/api/file-action.mjs +5 -0
  46. package/esm2022/chat/api/file-download-event.interface.mjs +5 -0
  47. package/esm2022/chat/api/index.mjs +8 -0
  48. package/esm2022/chat/api/message-action.mjs +5 -0
  49. package/esm2022/chat/api/message-toolbar-visibility.mjs +5 -0
  50. package/esm2022/chat/api/message-width-mode.mjs +5 -0
  51. package/esm2022/chat/api/send-button-settings.mjs +5 -0
  52. package/esm2022/chat/attachment.component.mjs +1 -1
  53. package/esm2022/chat/builtin-actions.mjs +1 -1
  54. package/esm2022/chat/cards/hero-card.component.mjs +1 -1
  55. package/esm2022/chat/chat-file.component.mjs +141 -0
  56. package/esm2022/chat/chat-item.mjs +1 -0
  57. package/esm2022/chat/chat-view.mjs +2 -2
  58. package/esm2022/chat/chat.component.mjs +518 -57
  59. package/esm2022/chat/chat.module.mjs +8 -4
  60. package/esm2022/chat/common/chat.service.mjs +97 -0
  61. package/esm2022/chat/common/models/default-model-fields.mjs +26 -0
  62. package/esm2022/chat/common/models/model-fields.mjs +5 -0
  63. package/esm2022/chat/common/utils.mjs +127 -0
  64. package/esm2022/chat/l10n/messages.mjs +60 -5
  65. package/esm2022/chat/message-attachments.component.mjs +1 -4
  66. package/esm2022/chat/message-box.component.mjs +360 -111
  67. package/esm2022/chat/message-list.component.mjs +166 -96
  68. package/esm2022/chat/message-reference-content.component.mjs +75 -0
  69. package/esm2022/chat/message.component.mjs +448 -35
  70. package/esm2022/chat/suggested-actions.component.mjs +151 -41
  71. package/esm2022/chat/templates/header-template.directive.mjs +33 -0
  72. package/esm2022/chat/{message-box.directive.mjs → templates/message-box.directive.mjs} +1 -1
  73. package/esm2022/chat/templates/status-template.directive.mjs +33 -0
  74. package/esm2022/chat/templates/suggestion-template.directive.mjs +33 -0
  75. package/esm2022/chat/templates/timestamp-template.directive.mjs +39 -0
  76. package/esm2022/conversational-ui.module.mjs +12 -8
  77. package/esm2022/directives.mjs +12 -4
  78. package/esm2022/index.mjs +9 -3
  79. package/esm2022/package-metadata.mjs +2 -2
  80. package/fesm2022/progress-kendo-angular-conversational-ui.mjs +4986 -3125
  81. package/index.d.ts +10 -3
  82. package/package.json +29 -12
  83. /package/chat/{attachment-template.directive.d.ts → templates/attachment-template.directive.d.ts} +0 -0
  84. /package/chat/{message-template.directive.d.ts → templates/message-template.directive.d.ts} +0 -0
  85. /package/esm2022/chat/{attachment-template.directive.mjs → templates/attachment-template.directive.mjs} +0 -0
  86. /package/esm2022/chat/{message-template.directive.mjs → templates/message-template.directive.mjs} +0 -0
@@ -2,20 +2,37 @@
2
2
  * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { Component, ContentChild, ElementRef, EventEmitter, HostBinding, Input, isDevMode, Output, ViewChild, NgZone } from '@angular/core';
6
- import { AttachmentTemplateDirective } from './attachment-template.directive';
5
+ import { Component, ContentChild, ElementRef, EventEmitter, HostBinding, Input, isDevMode, Output, ViewChild, NgZone, Renderer2, ViewContainerRef } from '@angular/core';
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 './message-template.directive';
9
+ import { MessageTemplateDirective } from './templates/message-template.directive';
10
+ import { Subscription } from 'rxjs';
10
11
  import { validatePackage } from '@progress/kendo-licensing';
11
12
  import { packageMetadata } from '../package-metadata';
12
- import { ChatMessageBoxTemplateDirective } from './message-box.directive';
13
+ import { ChatMessageBoxTemplateDirective } from './templates/message-box.directive';
13
14
  import { MessageBoxComponent } from './message-box.component';
14
15
  import { MessageListComponent } from './message-list.component';
15
16
  import { ScrollAnchorDirective } from './common/scroll-anchor.directive';
16
17
  import { LocalizedMessagesDirective } from './l10n/localized-messages.directive';
18
+ import { isChanged, isPresent, processCssValue } from '@progress/kendo-angular-common';
19
+ import { ChatService } from './common/chat.service';
20
+ import { AppBarComponent } from "@progress/kendo-angular-navigation";
21
+ import { ChatHeaderTemplateDirective } from './templates/header-template.directive';
22
+ import { NgIf, NgTemplateOutlet } from '@angular/common';
23
+ import { KENDO_BUTTON } from '@progress/kendo-angular-buttons';
24
+ import { pinIcon, xIcon } from '@progress/kendo-svg-icons';
25
+ import { IconWrapperComponent } from '@progress/kendo-angular-icons';
26
+ import { defaultModelFields } from './common/models/default-model-fields';
27
+ import { processMessages, SEND_BTN_DEFAULT_SETTINGS, FILE_ACTIONS, CONTEXT_MENU_ACTIONS } from './common/utils';
28
+ import { ChatTimestampTemplateDirective } from './templates/timestamp-template.directive';
29
+ import { MessageReferenceComponent } from './message-reference-content.component';
30
+ import { ChatStatusTemplateDirective } from './templates/status-template.directive';
31
+ import { ChatSuggestionTemplateDirective } from './templates/suggestion-template.directive';
17
32
  import * as i0 from "@angular/core";
18
33
  import * as i1 from "@progress/kendo-angular-l10n";
34
+ import * as i2 from "./common/chat.service";
35
+ import * as i3 from "@progress/kendo-angular-buttons";
19
36
  /**
20
37
  * Represents the [Kendo UI Chat component for Angular](slug:overview_convui).
21
38
  *
@@ -26,18 +43,21 @@ import * as i1 from "@progress/kendo-angular-l10n";
26
43
  * ```html
27
44
  * <kendo-chat
28
45
  * [messages]="messages"
29
- * [user]="user"
46
+ * [authorId]="authorId"
30
47
  * (sendMessage)="onSendMessage($event)"
31
48
  * (executeAction)="onExecuteAction($event)">
32
49
  * </kendo-chat>
33
50
  * ```
34
51
  *
35
52
  * @remarks
36
- * Supported children components are: {@link CustomMessagesComponent}, {@link HeroCardComponent}.
53
+ * Supported children components are: {@link CustomMessagesComponent}, {@link HeroCardComponent}, {@link AttachmentTemplateDirective}, {@link ChatHeaderTemplateDirective}, {@link ChatMessageBoxTemplateDirective}, {@link MessageTemplateDirective}, {@link ChatStatusTemplateDirective}, {@link ChatSuggestionTemplateDirective}, {@link ChatTimestampTemplateDirective}.
37
54
  */
38
55
  export class ChatComponent {
39
56
  localization;
40
57
  zone;
58
+ renderer;
59
+ element;
60
+ chatService;
41
61
  /**
42
62
  * Defines the array of messages displayed in the Chat.
43
63
  * Each message can include a timestamp for unique identification.
@@ -45,23 +65,154 @@ export class ChatComponent {
45
65
  */
46
66
  messages;
47
67
  /**
48
- * Specifies the [`User`](slug:api_conversational-ui_user) instance representing the local user.
49
- * The User ID is used to distinguish messages authored by the local user.
68
+ * Specifies the id representing the local user.
50
69
  */
51
- user;
70
+ authorId;
52
71
  /**
53
72
  * Determines the type of input used in the message box.
54
- * Can be set to `textbox` for a single-line input or `textarea` for multi-line input
55
- * ([see example](slug:message_box#message-box-types)).
56
- * @default 'textbox'
73
+ * ([see example](slug:message_chat)).
74
+ * @default 'textarea'
75
+ *
76
+ * @hidden
77
+ */
78
+ messageBoxType = 'textarea';
79
+ /**
80
+ * Sets the height of the Chat component.
81
+ * Accepts a string with CSS units (e.g., '400px', '50%') or a number (interpreted as pixels).
82
+ * The minimum height is `600px`.
83
+ */
84
+ height;
85
+ /**
86
+ * Sets the width of the Chat component.
87
+ * Accepts a string with CSS units (e.g., '400px', '50%') or a number (interpreted as pixels).
88
+ * The minimum width is `320px`.
89
+ */
90
+ width;
91
+ /**
92
+ * Sets the placeholder text for the message input box.
93
+ */
94
+ placeholder;
95
+ /**
96
+ * Switches the width of the message between the predefined options.
97
+ *
98
+ * @default 'standard'
99
+ */
100
+ messageWidthMode = 'standard';
101
+ /**
102
+ * Enables the expand/collapse functionality of the messages.
103
+ *
104
+ * @default `false`
105
+ */
106
+ allowMessageCollapse = false;
107
+ /**
108
+ * Sets the Speech to Text button settings.
109
+ *
110
+ * @default true
111
+ */
112
+ enableSpeechToText = true;
113
+ /**
114
+ * Sets the File Select settings.
115
+ *
116
+ * @default true
117
+ */
118
+ enableFileSelect = true;
119
+ /**
120
+ * Specifies the actions available in the message toolbar.
121
+ * These actions are displayed in the message toolbar and can be used to perform specific operations on the message.
122
+ *
123
+ * @default []
124
+ */
125
+ messageToolbarActions = [];
126
+ /**
127
+ * Sets the value of the Message Box.
128
+ */
129
+ inputValue = '';
130
+ /**
131
+ * Specifies the default actions available in the message context menu.
132
+ *
133
+ * @default [{ id: 'copy', label: 'Copy', icon: 'copy', svgIcon: copyIcon, disabled: false }, { id: 'reply', label: 'Reply', icon: 'undo', svgIcon: undoIcon, disabled: false }]
134
+ */
135
+ defaultContextMenuActions = CONTEXT_MENU_ACTIONS;
136
+ /**
137
+ * Specifies the actions available in the message as a context menu.
138
+ * These actions are displayed as menu items and can be used to perform specific operations on the message.
139
+ * The default actions are `copy` and `reply` and are defined by their `id`.
140
+ */
141
+ set messageContextMenuActions(actions) {
142
+ this._messageContextMenuActions = this.mergeWithDefaultActions(actions, CONTEXT_MENU_ACTIONS);
143
+ }
144
+ get messageContextMenuActions() {
145
+ return this._messageContextMenuActions;
146
+ }
147
+ /**
148
+ * Specifies the default actions available in the file actions DropDownButton.
149
+ */
150
+ defaultFileActions = FILE_ACTIONS;
151
+ /**
152
+ * Specifies the actions available in the file as items of a DropDownButton.
153
+ * These actions are displayed when clicking on the file DropDownButton and can be used to perform specific operations on the file.
154
+ * The default action is `download` and is defined by its `id`.
155
+ *
156
+ * @default [{ id: 'download', label: 'Download', icon: 'download', svgIcon: downloadIcon, disabled: false }]
157
+ */
158
+ set fileActions(actions) {
159
+ this._fileActions = this.mergeWithDefaultActions(actions, FILE_ACTIONS);
160
+ }
161
+ get fileActions() {
162
+ return this._fileActions;
163
+ }
164
+ /**
165
+ * Sets the suggestions to display in the message input box.
166
+ * Suggestions are displayed as a list of clickable items that can be used to quickly insert predefined text into the message input.
167
+ *
168
+ * @default []
169
+ */
170
+ suggestions = [];
171
+ /**
172
+ * Sets the visibility of the message toolbar.
173
+ *
174
+ * @default 'hidden'
175
+ */
176
+ messageToolbarVisibility = 'hidden';
177
+ /**
178
+ * Sets the send button settings for the Chat component.
179
+ * Allows customization of the send button appearance, icons and disabled state.
180
+ *
181
+ * @default defaultButtonSettings
57
182
  */
58
- messageBoxType = 'textbox';
183
+ sendButtonSettings = SEND_BTN_DEFAULT_SETTINGS;
184
+ /**
185
+ * Sets the names of the model fields from which the Chat reads its data.
186
+ * Allows mapping of custom data structures to the expected Message format.
187
+ */
188
+ set modelFields(value) {
189
+ this._modelFields = { ...defaultModelFields, ...value };
190
+ }
191
+ get modelFields() {
192
+ return this._modelFields;
193
+ }
59
194
  /**
60
195
  * Emits when the user sends a message by clicking the **Send** button or pressing **Enter**.
61
196
  *
62
197
  * > The message is not automatically added to the `messages` array.
63
198
  */
64
199
  sendMessage = new EventEmitter();
200
+ /**
201
+ * Emits when the user clicks a quick action button in the message toolbar.
202
+ */
203
+ toolbarActionClick = new EventEmitter();
204
+ /**
205
+ * Emits when the user clicks an action in the message context menu.
206
+ */
207
+ contextMenuActionClick = new EventEmitter();
208
+ /**
209
+ * Emits when the user clicks an action in the file context menu.
210
+ */
211
+ fileActionClick = new EventEmitter();
212
+ /**
213
+ * Emits when the user clicks an action in the file context menu.
214
+ */
215
+ download = new EventEmitter();
65
216
  /**
66
217
  * Emits when the user clicks a quick action button.
67
218
  * The Chat internally handles [known actions](slug:api_conversational-ui_actiontype) such as `reply`, `openUrl`, and `call`.
@@ -69,6 +220,27 @@ export class ChatComponent {
69
220
  * The event is preventable&mdash;calling `preventDefault` suppresses the built-in action.
70
221
  */
71
222
  executeAction = new EventEmitter();
223
+ /**
224
+ * Emits when the user clicks a suggestion in the message input box.
225
+ */
226
+ suggestionExecute = new EventEmitter();
227
+ /**
228
+ * Emits when the user selects a file in the message input box.
229
+ */
230
+ fileSelect = new EventEmitter();
231
+ /**
232
+ * Emits when the user removes a file from the message input box.
233
+ */
234
+ fileRemove = new EventEmitter();
235
+ /**
236
+ * Emits when the user unpins the pinned message.
237
+ * This event is triggered when the user clicks the delete button on the pinned message.
238
+ */
239
+ unpin = new EventEmitter();
240
+ /**
241
+ * Emits when the user types in the message input box.
242
+ */
243
+ inputValueChange = new EventEmitter();
72
244
  get className() {
73
245
  return 'k-chat';
74
246
  }
@@ -76,13 +248,30 @@ export class ChatComponent {
76
248
  return this.direction;
77
249
  }
78
250
  attachmentTemplate;
251
+ chatHeaderTemplate;
79
252
  messageTemplate;
253
+ timestampTemplate;
254
+ suggestionTemplate;
255
+ statusTemplate;
80
256
  messageBoxTemplate;
81
257
  messageBox;
82
258
  /**
83
259
  * @hidden
84
260
  */
85
261
  messageList;
262
+ /**
263
+ * @hidden
264
+ * Returns processed messages when model fields are used, otherwise returns original messages
265
+ */
266
+ get processedMessages() {
267
+ if (!this.messages || this.messages.length === 0) {
268
+ return [];
269
+ }
270
+ if (this._modelFields && Object.keys(this._modelFields).some(key => this._modelFields[key] !== defaultModelFields[key])) {
271
+ return processMessages(this.messages, this._modelFields);
272
+ }
273
+ return this.messages;
274
+ }
86
275
  /**
87
276
  * @hidden
88
277
  */
@@ -93,33 +282,115 @@ export class ChatComponent {
93
282
  * @hidden
94
283
  */
95
284
  autoScroll = true;
285
+ /**
286
+ * @hidden
287
+ */
288
+ pinIcon = pinIcon;
289
+ /**
290
+ * @hidden
291
+ */
292
+ deleteIcon = xIcon;
293
+ /**
294
+ * @hidden
295
+ */
296
+ pinnedMessage;
96
297
  direction;
97
- localizationChangeSubscription;
98
- constructor(localization, zone) {
298
+ subs = new Subscription();
299
+ _modelFields = defaultModelFields;
300
+ _messageContextMenuActions = CONTEXT_MENU_ACTIONS;
301
+ _fileActions = FILE_ACTIONS;
302
+ constructor(localization, zone, renderer, element, chatService) {
99
303
  this.localization = localization;
100
304
  this.zone = zone;
305
+ this.renderer = renderer;
306
+ this.element = element;
307
+ this.chatService = chatService;
101
308
  validatePackage(packageMetadata);
102
309
  this.direction = localization.rtl ? 'rtl' : 'ltr';
103
- this.localizationChangeSubscription = localization.changes.subscribe(({ rtl }) => {
310
+ this.subs.add(localization.changes.subscribe(({ rtl }) => {
104
311
  this.direction = rtl ? 'rtl' : 'ltr';
105
- });
312
+ }));
106
313
  }
107
- ngOnChanges() {
314
+ /**
315
+ * @hidden
316
+ */
317
+ ngOnInit() {
318
+ this.chatService.messageWidthMode = this.messageWidthMode;
319
+ this.chatService.allowMessageCollapse = this.allowMessageCollapse;
320
+ this.chatService.enableSpeechToText = this.enableSpeechToText;
321
+ this.chatService.sendButtonSettings = this.sendButtonSettings;
322
+ this.chatService.enableFileSelect = this.enableFileSelect;
323
+ this.chatService.messageToolbarActions = this.messageToolbarActions;
324
+ this.chatService.messageContextMenuActions = this.messageContextMenuActions;
325
+ this.chatService.fileActions = this.fileActions;
326
+ this.chatService.messageToolbarVisibility = this.messageToolbarVisibility;
327
+ this.chatService.messages = this.processedMessages || [];
328
+ this.chatService.chatElement = this.messageList;
329
+ this.subs.add(this.chatService.toolbarAction$.subscribe((actionEvent) => {
330
+ this.toolbarActionClick.emit(actionEvent);
331
+ }));
332
+ this.subs.add(this.chatService.contextMenuAction$.subscribe((actionEvent) => {
333
+ this.contextMenuActionClick.emit(actionEvent);
334
+ }));
335
+ this.subs.add(this.chatService.fileAction$.subscribe((actionEvent) => {
336
+ this.fileActionClick.emit(actionEvent);
337
+ }));
338
+ this.subs.add(this.chatService.fileDownload$.subscribe((actionEvent) => {
339
+ this.download.emit(actionEvent);
340
+ }));
341
+ this.subs.add(this.chatService.inputValueChange$.subscribe((value) => {
342
+ this.inputValueChange.emit(value);
343
+ }));
344
+ this.pinnedMessage = this.findLastPinnedMessage();
345
+ this.chatService.authorId = this.authorId;
346
+ }
347
+ /**
348
+ * @hidden
349
+ */
350
+ ngOnChanges(changes) {
108
351
  this.zone.runOutsideAngular(() => setTimeout(() => {
109
- this.messageList.nativeElement.style.flex = '1 1 auto';
352
+ this.messageList.element.nativeElement.style.flex = '1 1 auto';
110
353
  }));
354
+ if (isChanged('messages', changes, false)) {
355
+ this.pinnedMessage = this.findLastPinnedMessage();
356
+ this.chatService.messages = this.processedMessages;
357
+ }
358
+ if (isChanged('height', changes, false)) {
359
+ this.renderer.setStyle(this.element.nativeElement, 'height', `${processCssValue(this.height)}`);
360
+ }
361
+ if (isChanged('width', changes, false)) {
362
+ this.renderer.setStyle(this.element.nativeElement, 'width', `${processCssValue(this.width)}`);
363
+ }
364
+ this.updateChatServiceProperties([
365
+ 'authorId',
366
+ 'messageWidthMode',
367
+ 'allowMessageCollapse',
368
+ 'enableSpeechToText',
369
+ 'sendButtonSettings',
370
+ 'enableFileSelect',
371
+ 'messageToolbarActions',
372
+ 'messageContextMenuActions',
373
+ 'fileActions',
374
+ 'messageToolbarVisibility'
375
+ ], changes);
111
376
  }
377
+ /**
378
+ * @hidden
379
+ */
112
380
  ngAfterViewInit() {
113
381
  if (!isDevMode()) {
114
382
  return;
115
383
  }
116
- if (!this.user) {
117
- throw new Error('User must be set and have a valid id.');
384
+ if (!isPresent(this.authorId)) {
385
+ throw new Error('AuthorId must be set.');
118
386
  }
119
387
  }
388
+ /**
389
+ * @hidden
390
+ */
120
391
  ngOnDestroy() {
121
- if (this.localizationChangeSubscription) {
122
- this.localizationChangeSubscription.unsubscribe();
392
+ if (this.subs) {
393
+ this.subs.unsubscribe();
123
394
  }
124
395
  }
125
396
  /**
@@ -141,15 +412,52 @@ export class ChatComponent {
141
412
  textFor(key) {
142
413
  return this.localization.get(key);
143
414
  }
144
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChatComponent, deps: [{ token: i1.LocalizationService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
145
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ChatComponent, isStandalone: true, selector: "kendo-chat", inputs: { messages: "messages", user: "user", messageBoxType: "messageBoxType" }, outputs: { sendMessage: "sendMessage", executeAction: "executeAction" }, host: { properties: { "class": "this.className", "attr.dir": "this.dirAttr" } }, providers: [
415
+ /**
416
+ * @hidden
417
+ */
418
+ scrollToPinnedMessage() {
419
+ if (this.pinnedMessage) {
420
+ this.chatService.scrollToMessage(this.pinnedMessage?.id);
421
+ }
422
+ }
423
+ findLastPinnedMessage() {
424
+ return [...this.processedMessages].reverse().find((message) => message.isPinned);
425
+ }
426
+ updateChatServiceProperties(propNames, changes) {
427
+ propNames.forEach(propName => {
428
+ if (isChanged(propName, changes, false)) {
429
+ this.chatService[propName] = this[propName];
430
+ }
431
+ });
432
+ }
433
+ mergeWithDefaultActions(actions, defaultActions) {
434
+ if (!actions || actions.length === 0) {
435
+ return [];
436
+ }
437
+ return actions.map(userAction => {
438
+ const defaultAction = defaultActions.find(action => action.id === userAction?.id);
439
+ if (defaultAction) {
440
+ return { ...defaultAction, ...userAction };
441
+ }
442
+ return userAction;
443
+ });
444
+ }
445
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChatComponent, deps: [{ token: i1.LocalizationService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i2.ChatService }], target: i0.ɵɵFactoryTarget.Component });
446
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", 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: [
146
447
  LocalizationService,
448
+ ChatService,
147
449
  {
148
450
  provide: L10N_PREFIX,
149
451
  useValue: 'kendo.chat'
150
452
  }
151
- ], queries: [{ propertyName: "attachmentTemplate", first: true, predicate: AttachmentTemplateDirective, descendants: true }, { propertyName: "messageTemplate", first: true, predicate: MessageTemplateDirective, 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, static: true }], usesOnChanges: true, ngImport: i0, template: `
453
+ ], 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: `
152
454
  <ng-container kendoChatLocalizedMessages
455
+ i18n-deletedMessageSenderText="kendo.chat.deletedMessageSenderText|The text that is displayed when the sender deletes a message"
456
+ deletedMessageSenderText="You removed this message."
457
+
458
+ i18n-deletedMessageReceiverText="kendo.chat.deletedMessageReceiverText|The text that is displayed when the receiver deletes a message"
459
+ deletedMessageReceiverText="This message was removed by its sender."
460
+
153
461
  i18n-messagePlaceholder="kendo.chat.messagePlaceholder|The placholder text of the message text input"
154
462
  messagePlaceholder="Type a message..."
155
463
 
@@ -168,11 +476,46 @@ export class ChatComponent {
168
476
  i18n-messageAttachmentRightArrow="kendo.chat.messageAttachmentRightArrow|The text for the right arrow of the message attachments"
169
477
  messageAttachmentRightArrow="Next item"
170
478
 
171
- i18n-messageAvatarAlt="kendo.chat.messageAvatarAlt|The alt attribute text for the avatar"
172
- messageAvatarAlt="Avatar"
479
+ i18n-speechToTextButtonTitle="kendo.chat.speechToTextButtonTitle|Sets the Speech to Text button title."
480
+ speechToTextButtonTitle="Speech to Text"
481
+
482
+ i18n-fileSelectButtonTitle="kendo.chat.fileSelectButtonTitle|Sets the File Select button title."
483
+ fileSelectButtonTitle="Select files"
484
+
485
+ i18n-removeReplyTitle="kendo.chat.removeReplyTitle|Sets the title of the icon which removes the reply reference in the Message Box."
486
+ removeReplyTitle="Remove reply"
487
+
488
+ i18n-removeFileTitle="kendo.chat.removeFileTitle|Sets the title of the icon which removes a selected file in the Message Box."
489
+ removeFileTitle="Remove file"
490
+
491
+ i18n-expandTitle="kendo.chat.expandTitle|Sets the title of the icon which demonstrates that the message can be expanded."
492
+ expandTitle="Expand message"
493
+
494
+ i18n-collapseTitle="kendo.chat.collapseTitle|Sets the title of the icon which demonstrates that the message can be collapsed."
495
+ collapseTitle="Collapse message"
496
+
497
+ i18n-fileActionsTitle="kendo.chat.fileActionsTitle|Sets the title of the DropDownButton which opens the File actions."
498
+ fileActionsTitle="File actions"
499
+
500
+ i18n-downloadAllFilesText="kendo.chat.downloadAllFilesText|Sets the text that is displayed in the download section of the message."
501
+ downloadAllFilesText="Download all"
173
502
  >
174
503
  </ng-container>
175
504
 
505
+ <kendo-appbar *ngIf="chatHeaderTemplate" class="k-chat-header" positionMode="sticky">
506
+ <ng-container *ngTemplateOutlet="chatHeaderTemplate.templateRef"></ng-container>
507
+ </kendo-appbar>
508
+ <div class="k-message-reference k-message-reference-receiver k-message-pinned" *ngIf="pinnedMessage" (click)="scrollToPinnedMessage()">
509
+ <kendo-icon-wrapper
510
+ size="xlarge"
511
+ name="pin"
512
+ [svgIcon]="pinIcon"
513
+ >
514
+ </kendo-icon-wrapper>
515
+ <chat-message-reference-content [message]="pinnedMessage"></chat-message-reference-content>
516
+ <span class="k-spacer"></span>
517
+ <button kendoButton [svgIcon]="deleteIcon" (click)="unpin.emit(pinnedMessage)" fillMode="flat"></button>
518
+ </div>
176
519
  <div
177
520
  #messageList
178
521
  class="k-message-list k-avatars"
@@ -184,11 +527,13 @@ export class ChatComponent {
184
527
  [(autoScroll)]="autoScroll"
185
528
  >
186
529
  <kendo-chat-message-list
187
- [messages]="messages"
530
+ [messages]="processedMessages"
188
531
  [messageTemplate]="messageTemplate"
532
+ [timestampTemplate]="timestampTemplate"
533
+ [statusTemplate]="statusTemplate"
189
534
  [localization]="localizationText"
190
535
  [attachmentTemplate]="attachmentTemplate"
191
- [user]="user"
536
+ [authorId]="authorId"
192
537
  (executeAction)="dispatchAction($event)"
193
538
  (resize)="anchor.scrollToBottom()"
194
539
  (navigate)="this.autoScroll = false"
@@ -196,22 +541,29 @@ export class ChatComponent {
196
541
  </kendo-chat-message-list>
197
542
  </div>
198
543
  <kendo-message-box
199
- #messageBox
200
- [messageBoxTemplate]="messageBoxTemplate"
201
- [type]="messageBoxType"
202
- [user]="user"
203
- [autoScroll]="autoScroll"
204
- [localization]="localizationText"
205
- (sendMessage)="sendMessage.emit($event)"
544
+ #messageBox
545
+ [messageBoxTemplate]="messageBoxTemplate"
546
+ [suggestionTemplate]="suggestionTemplate"
547
+ [suggestions]="suggestions"
548
+ [placeholder]="placeholder"
549
+ [authorId]="authorId"
550
+ [autoScroll]="autoScroll"
551
+ [inputValue]="inputValue"
552
+ [localization]="localizationText"
553
+ (sendMessage)="sendMessage.emit($event)"
554
+ (executeSuggestion)="suggestionExecute.emit($event)"
555
+ (fileSelect)="fileSelect.emit($event)"
556
+ (fileRemove)="fileRemove.emit($event)"
206
557
  >
207
558
  </kendo-message-box>
208
- `, 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", "localization", "user"], outputs: ["executeAction", "navigate", "resize"] }, { kind: "component", type: MessageBoxComponent, selector: "kendo-message-box", inputs: ["user", "autoScroll", "type", "localization", "messageBoxTemplate"], outputs: ["sendMessage"] }] });
559
+ `, 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"] }] });
209
560
  }
210
561
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChatComponent, decorators: [{
211
562
  type: Component,
212
563
  args: [{
213
564
  providers: [
214
565
  LocalizationService,
566
+ ChatService,
215
567
  {
216
568
  provide: L10N_PREFIX,
217
569
  useValue: 'kendo.chat'
@@ -220,6 +572,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
220
572
  selector: 'kendo-chat',
221
573
  template: `
222
574
  <ng-container kendoChatLocalizedMessages
575
+ i18n-deletedMessageSenderText="kendo.chat.deletedMessageSenderText|The text that is displayed when the sender deletes a message"
576
+ deletedMessageSenderText="You removed this message."
577
+
578
+ i18n-deletedMessageReceiverText="kendo.chat.deletedMessageReceiverText|The text that is displayed when the receiver deletes a message"
579
+ deletedMessageReceiverText="This message was removed by its sender."
580
+
223
581
  i18n-messagePlaceholder="kendo.chat.messagePlaceholder|The placholder text of the message text input"
224
582
  messagePlaceholder="Type a message..."
225
583
 
@@ -238,11 +596,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
238
596
  i18n-messageAttachmentRightArrow="kendo.chat.messageAttachmentRightArrow|The text for the right arrow of the message attachments"
239
597
  messageAttachmentRightArrow="Next item"
240
598
 
241
- i18n-messageAvatarAlt="kendo.chat.messageAvatarAlt|The alt attribute text for the avatar"
242
- messageAvatarAlt="Avatar"
599
+ i18n-speechToTextButtonTitle="kendo.chat.speechToTextButtonTitle|Sets the Speech to Text button title."
600
+ speechToTextButtonTitle="Speech to Text"
601
+
602
+ i18n-fileSelectButtonTitle="kendo.chat.fileSelectButtonTitle|Sets the File Select button title."
603
+ fileSelectButtonTitle="Select files"
604
+
605
+ i18n-removeReplyTitle="kendo.chat.removeReplyTitle|Sets the title of the icon which removes the reply reference in the Message Box."
606
+ removeReplyTitle="Remove reply"
607
+
608
+ i18n-removeFileTitle="kendo.chat.removeFileTitle|Sets the title of the icon which removes a selected file in the Message Box."
609
+ removeFileTitle="Remove file"
610
+
611
+ i18n-expandTitle="kendo.chat.expandTitle|Sets the title of the icon which demonstrates that the message can be expanded."
612
+ expandTitle="Expand message"
613
+
614
+ i18n-collapseTitle="kendo.chat.collapseTitle|Sets the title of the icon which demonstrates that the message can be collapsed."
615
+ collapseTitle="Collapse message"
616
+
617
+ i18n-fileActionsTitle="kendo.chat.fileActionsTitle|Sets the title of the DropDownButton which opens the File actions."
618
+ fileActionsTitle="File actions"
619
+
620
+ i18n-downloadAllFilesText="kendo.chat.downloadAllFilesText|Sets the text that is displayed in the download section of the message."
621
+ downloadAllFilesText="Download all"
243
622
  >
244
623
  </ng-container>
245
624
 
625
+ <kendo-appbar *ngIf="chatHeaderTemplate" class="k-chat-header" positionMode="sticky">
626
+ <ng-container *ngTemplateOutlet="chatHeaderTemplate.templateRef"></ng-container>
627
+ </kendo-appbar>
628
+ <div class="k-message-reference k-message-reference-receiver k-message-pinned" *ngIf="pinnedMessage" (click)="scrollToPinnedMessage()">
629
+ <kendo-icon-wrapper
630
+ size="xlarge"
631
+ name="pin"
632
+ [svgIcon]="pinIcon"
633
+ >
634
+ </kendo-icon-wrapper>
635
+ <chat-message-reference-content [message]="pinnedMessage"></chat-message-reference-content>
636
+ <span class="k-spacer"></span>
637
+ <button kendoButton [svgIcon]="deleteIcon" (click)="unpin.emit(pinnedMessage)" fillMode="flat"></button>
638
+ </div>
246
639
  <div
247
640
  #messageList
248
641
  class="k-message-list k-avatars"
@@ -254,11 +647,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
254
647
  [(autoScroll)]="autoScroll"
255
648
  >
256
649
  <kendo-chat-message-list
257
- [messages]="messages"
650
+ [messages]="processedMessages"
258
651
  [messageTemplate]="messageTemplate"
652
+ [timestampTemplate]="timestampTemplate"
653
+ [statusTemplate]="statusTemplate"
259
654
  [localization]="localizationText"
260
655
  [attachmentTemplate]="attachmentTemplate"
261
- [user]="user"
656
+ [authorId]="authorId"
262
657
  (executeAction)="dispatchAction($event)"
263
658
  (resize)="anchor.scrollToBottom()"
264
659
  (navigate)="this.autoScroll = false"
@@ -266,29 +661,83 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
266
661
  </kendo-chat-message-list>
267
662
  </div>
268
663
  <kendo-message-box
269
- #messageBox
270
- [messageBoxTemplate]="messageBoxTemplate"
271
- [type]="messageBoxType"
272
- [user]="user"
273
- [autoScroll]="autoScroll"
274
- [localization]="localizationText"
275
- (sendMessage)="sendMessage.emit($event)"
664
+ #messageBox
665
+ [messageBoxTemplate]="messageBoxTemplate"
666
+ [suggestionTemplate]="suggestionTemplate"
667
+ [suggestions]="suggestions"
668
+ [placeholder]="placeholder"
669
+ [authorId]="authorId"
670
+ [autoScroll]="autoScroll"
671
+ [inputValue]="inputValue"
672
+ [localization]="localizationText"
673
+ (sendMessage)="sendMessage.emit($event)"
674
+ (executeSuggestion)="suggestionExecute.emit($event)"
675
+ (fileSelect)="fileSelect.emit($event)"
676
+ (fileRemove)="fileRemove.emit($event)"
276
677
  >
277
678
  </kendo-message-box>
278
679
  `,
279
680
  standalone: true,
280
- imports: [LocalizedMessagesDirective, ScrollAnchorDirective, MessageListComponent, MessageBoxComponent]
681
+ imports: [LocalizedMessagesDirective, ScrollAnchorDirective, MessageListComponent, MessageBoxComponent, MessageReferenceComponent, AppBarComponent, NgTemplateOutlet, NgIf, IconWrapperComponent, KENDO_BUTTON]
281
682
  }]
282
- }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i0.NgZone }]; }, propDecorators: { messages: [{
683
+ }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i2.ChatService }]; }, propDecorators: { messages: [{
283
684
  type: Input
284
- }], user: [{
685
+ }], authorId: [{
285
686
  type: Input
286
687
  }], messageBoxType: [{
287
688
  type: Input
689
+ }], height: [{
690
+ type: Input
691
+ }], width: [{
692
+ type: Input
693
+ }], placeholder: [{
694
+ type: Input
695
+ }], messageWidthMode: [{
696
+ type: Input
697
+ }], allowMessageCollapse: [{
698
+ type: Input
699
+ }], enableSpeechToText: [{
700
+ type: Input
701
+ }], enableFileSelect: [{
702
+ type: Input
703
+ }], messageToolbarActions: [{
704
+ type: Input
705
+ }], inputValue: [{
706
+ type: Input
707
+ }], messageContextMenuActions: [{
708
+ type: Input
709
+ }], fileActions: [{
710
+ type: Input
711
+ }], suggestions: [{
712
+ type: Input
713
+ }], messageToolbarVisibility: [{
714
+ type: Input
715
+ }], sendButtonSettings: [{
716
+ type: Input
717
+ }], modelFields: [{
718
+ type: Input
288
719
  }], sendMessage: [{
289
720
  type: Output
721
+ }], toolbarActionClick: [{
722
+ type: Output
723
+ }], contextMenuActionClick: [{
724
+ type: Output
725
+ }], fileActionClick: [{
726
+ type: Output
727
+ }], download: [{
728
+ type: Output
290
729
  }], executeAction: [{
291
730
  type: Output
731
+ }], suggestionExecute: [{
732
+ type: Output
733
+ }], fileSelect: [{
734
+ type: Output
735
+ }], fileRemove: [{
736
+ type: Output
737
+ }], unpin: [{
738
+ type: Output
739
+ }], inputValueChange: [{
740
+ type: Output
292
741
  }], className: [{
293
742
  type: HostBinding,
294
743
  args: ['class']
@@ -297,17 +746,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
297
746
  args: ['attr.dir']
298
747
  }], attachmentTemplate: [{
299
748
  type: ContentChild,
300
- args: [AttachmentTemplateDirective, { static: false }]
749
+ args: [AttachmentTemplateDirective]
750
+ }], chatHeaderTemplate: [{
751
+ type: ContentChild,
752
+ args: [ChatHeaderTemplateDirective]
301
753
  }], messageTemplate: [{
302
754
  type: ContentChild,
303
- args: [MessageTemplateDirective, { static: false }]
755
+ args: [MessageTemplateDirective]
756
+ }], timestampTemplate: [{
757
+ type: ContentChild,
758
+ args: [ChatTimestampTemplateDirective]
759
+ }], suggestionTemplate: [{
760
+ type: ContentChild,
761
+ args: [ChatSuggestionTemplateDirective]
762
+ }], statusTemplate: [{
763
+ type: ContentChild,
764
+ args: [ChatStatusTemplateDirective]
304
765
  }], messageBoxTemplate: [{
305
766
  type: ContentChild,
306
- args: [ChatMessageBoxTemplateDirective, { static: false }]
767
+ args: [ChatMessageBoxTemplateDirective]
307
768
  }], messageBox: [{
308
769
  type: ViewChild,
309
- args: ['messageBox', { static: false }]
770
+ args: ['messageBox']
310
771
  }], messageList: [{
311
772
  type: ViewChild,
312
- args: ['messageList', { static: true }]
773
+ args: ['messageList', { static: true, read: ViewContainerRef }]
313
774
  }] } });