@progress/kendo-angular-conversational-ui 21.1.1-develop.2 → 21.2.0-develop.10

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 (27) hide show
  1. package/chat/chat.component.d.ts +2 -0
  2. package/chat/message-list.component.d.ts +2 -2
  3. package/codemods/utils.js +805 -394
  4. package/codemods/v20/chat-user.js +9 -12
  5. package/codemods/v21/chat-messagetoolbarvisibility.js +9 -13
  6. package/codemods/v21/chat-pinnedbyfield.js +1 -2
  7. package/esm2022/ai-prompt/aiprompt.component.mjs +155 -139
  8. package/esm2022/ai-prompt/common/output-card.component.mjs +81 -83
  9. package/esm2022/ai-prompt/common/toolbar-focusable.directive.mjs +2 -2
  10. package/esm2022/ai-prompt/views/output-view.component.mjs +27 -29
  11. package/esm2022/ai-prompt/views/prompt-view.component.mjs +150 -135
  12. package/esm2022/chat/attachment.component.mjs +53 -37
  13. package/esm2022/chat/cards/hero-card.component.mjs +48 -35
  14. package/esm2022/chat/chat-file.component.mjs +32 -29
  15. package/esm2022/chat/chat-view.mjs +2 -2
  16. package/esm2022/chat/chat.component.mjs +259 -242
  17. package/esm2022/chat/message-attachments.component.mjs +60 -55
  18. package/esm2022/chat/message-box.component.mjs +203 -183
  19. package/esm2022/chat/message-list.component.mjs +249 -209
  20. package/esm2022/chat/message-reference-content.component.mjs +30 -19
  21. package/esm2022/chat/message.component.mjs +301 -281
  22. package/esm2022/chat/suggested-actions.component.mjs +142 -134
  23. package/esm2022/inline-ai-prompt/inlineaiprompt-content.component.mjs +205 -179
  24. package/esm2022/package-metadata.mjs +2 -2
  25. package/fesm2022/progress-kendo-angular-conversational-ui.mjs +1988 -1777
  26. package/package.json +14 -14
  27. package/codemods/template-transformer/index.js +0 -93
@@ -5,9 +5,9 @@
5
5
  /* eslint-disable @typescript-eslint/no-unused-vars */
6
6
  /* eslint-disable @typescript-eslint/no-explicit-any */
7
7
  import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, Input, Output, QueryList, Renderer2, ViewChildren } from '@angular/core';
8
- import { NgFor, NgSwitch, NgSwitchCase, NgIf, NgTemplateOutlet } from '@angular/common';
8
+ import { NgTemplateOutlet } from '@angular/common';
9
9
  import { ExecuteActionEvent } from './api';
10
- import { isPresent, Keys, normalizeNumpadKeys, ResizeSensorComponent } from '@progress/kendo-angular-common';
10
+ import { isPresent, Keys, normalizeKeys, ResizeSensorComponent } from '@progress/kendo-angular-common';
11
11
  import { IntlService } from '@progress/kendo-angular-intl';
12
12
  import { LocalizationService } from '@progress/kendo-angular-l10n';
13
13
  import { closest, DOWNLOAD_ALL_SELECTOR, FILE_ACTION_BTN_SELECTOR } from './common/utils';
@@ -121,20 +121,6 @@ export class MessageListComponent {
121
121
  onClick(message, event) {
122
122
  this.select(message, event);
123
123
  }
124
- showGroupAuthor(group) {
125
- const messageSettings = this.isOwnMessage(group.messages[0]) ? this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
126
- if (isPresent(messageSettings?.showUsername)) {
127
- return messageSettings.showUsername && group.author.name;
128
- }
129
- return this.chatService.showUsername && group.author.name;
130
- }
131
- showGroupAvatar(group) {
132
- const messageSettings = this.isOwnMessage(group.messages[0]) ? this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
133
- if (isPresent(messageSettings?.showAvatar)) {
134
- return messageSettings.showAvatar && group.author.avatarUrl;
135
- }
136
- return this.chatService.showAvatar && group.author.avatarUrl;
137
- }
138
124
  onContextMenuClick(message, event, messageElement) {
139
125
  this.chatService.calculateContextMenuActions(this.isOwnMessage(message));
140
126
  if (this.chatService.calculatedContextMenuActions.length > 0) {
@@ -162,7 +148,7 @@ export class MessageListComponent {
162
148
  }
163
149
  onKeydown(e) {
164
150
  // On some keyboards Numpad keys are used for Home/End/PageUp/PageDown.
165
- const code = normalizeNumpadKeys(e);
151
+ const code = normalizeKeys(e);
166
152
  const action = this.keyActions[code];
167
153
  if (action) {
168
154
  action(e);
@@ -179,6 +165,22 @@ export class MessageListComponent {
179
165
  isOwnMessage(msg) {
180
166
  return isAuthor(this.authorId, msg);
181
167
  }
168
+ showGroupAuthor(group) {
169
+ const messageSettings = this.isOwnMessage(group.messages[0]) ?
170
+ this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
171
+ if (isPresent(messageSettings?.showUsername)) {
172
+ return messageSettings.showUsername && group.author.name;
173
+ }
174
+ return this.chatService.showUsername && group.author.name;
175
+ }
176
+ showGroupAvatar(group) {
177
+ const messageSettings = this.isOwnMessage(group.messages[0]) ?
178
+ this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
179
+ if (isPresent(messageSettings?.showAvatar)) {
180
+ return messageSettings.showAvatar && group.author.avatarUrl;
181
+ }
182
+ return this.chatService.showAvatar && group.author.avatarUrl;
183
+ }
182
184
  dispatchAction(action, message) {
183
185
  const args = new ExecuteActionEvent(action, message);
184
186
  this.executeAction.emit(args);
@@ -310,231 +312,269 @@ export class MessageListComponent {
310
312
  });
311
313
  }
312
314
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageListComponent, deps: [{ token: i0.ElementRef }, { token: i1.IntlService }, { token: i0.Renderer2 }, { token: i2.ChatService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
313
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MessageListComponent, isStandalone: true, selector: "kendo-chat-message-list", inputs: { messages: "messages", attachmentTemplate: "attachmentTemplate", authorMessageContentTemplate: "authorMessageContentTemplate", receiverMessageContentTemplate: "receiverMessageContentTemplate", messageContentTemplate: "messageContentTemplate", authorMessageTemplate: "authorMessageTemplate", receiverMessageTemplate: "receiverMessageTemplate", messageTemplate: "messageTemplate", timestampTemplate: "timestampTemplate", statusTemplate: "statusTemplate", userStatusTemplate: "userStatusTemplate", localization: "localization", authorId: "authorId" }, outputs: { executeAction: "executeAction", navigate: "navigate", resize: "resize" }, host: { properties: { "class.k-message-list-content": "this.cssClass" } }, viewQueries: [{ propertyName: "items", predicate: ChatItem, descendants: true }], ngImport: i0, template: `
314
- <ng-container *ngFor="let group of view; last as lastGroup; trackBy: trackGroup">
315
- <ng-container [ngSwitch]="group.type">
316
- <div
317
- *ngSwitchCase="'date-marker'"
318
- class="k-timestamp"
315
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MessageListComponent, isStandalone: true, selector: "kendo-chat-message-list", inputs: { messages: "messages", attachmentTemplate: "attachmentTemplate", authorMessageContentTemplate: "authorMessageContentTemplate", receiverMessageContentTemplate: "receiverMessageContentTemplate", messageContentTemplate: "messageContentTemplate", authorMessageTemplate: "authorMessageTemplate", receiverMessageTemplate: "receiverMessageTemplate", messageTemplate: "messageTemplate", timestampTemplate: "timestampTemplate", statusTemplate: "statusTemplate", userStatusTemplate: "userStatusTemplate", localization: "localization", authorId: "authorId" }, outputs: { executeAction: "executeAction", navigate: "navigate", resize: "resize" }, host: { properties: { "class.k-message-list-content": "this.cssClass" } }, viewQueries: [{ propertyName: "items", predicate: ChatItem, descendants: true }], ngImport: i0, template: `
316
+ @for (group of view; track trackGroup($index, group); let lastGroup = $last) {
317
+ @switch (group.type) {
318
+ @case ('date-marker') {
319
+ <div
320
+ class="k-timestamp"
319
321
  >
320
- <ng-container
321
- *ngIf="timestampTemplate?.templateRef"
322
- [ngTemplateOutlet]="timestampTemplate.templateRef"
323
- [ngTemplateOutletContext]="{ $implicit: group.timestamp }"
322
+ @if (timestampTemplate?.templateRef) {
323
+ <ng-container
324
+ [ngTemplateOutlet]="timestampTemplate.templateRef"
325
+ [ngTemplateOutletContext]="{ $implicit: group.timestamp }"
324
326
  >
325
- </ng-container>
326
- <ng-container *ngIf="!timestampTemplate?.templateRef">{{ formatTimeStamp(group.timestamp) }}</ng-container>
327
- </div>
328
- <div
329
- *ngSwitchCase="'message-group'"
330
- class="k-message-group"
331
- [class.k-message-group-sender]="isOwnMessage(group.messages[0])"
332
- [class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
333
- [class.k-no-avatar]="!showGroupAvatar(group)"
334
- [class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
327
+ </ng-container>
328
+ }
329
+ @if (!timestampTemplate?.templateRef) {
330
+ {{ formatTimeStamp(group.timestamp) }}
331
+ }
332
+ </div>
333
+ }
334
+ @case ('message-group') {
335
+ <div
336
+ class="k-message-group"
337
+ [class.k-message-group-sender]="isOwnMessage(group.messages[0])"
338
+ [class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
339
+ [class.k-no-avatar]="!showGroupAvatar(group)"
340
+ [class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
335
341
  >
342
+ @if (!userStatusTemplate?.templateRef && showGroupAvatar(group)) {
343
+ <div
344
+ class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
345
+ >
346
+ <span class="k-avatar-image">
347
+ <img
348
+ [attr.src]="group.author.avatarUrl"
349
+ [alt]="group.author.avatarAltText"
350
+ />
351
+ </span>
352
+ </div>
353
+ }
354
+ @if (showGroupAvatar(group) && userStatusTemplate?.templateRef) {
355
+ <div class="k-chat-user-status-wrapper">
336
356
  <div
337
- *ngIf="!userStatusTemplate?.templateRef && showGroupAvatar(group)"
357
+ class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
358
+ >
359
+ <span class="k-avatar-image">
360
+ <img
361
+ [attr.src]="group.author.avatarUrl"
362
+ [alt]="group.author.avatarAltText"
363
+ />
364
+ </span>
365
+ </div>
366
+ @if (userStatusTemplate?.templateRef) {
367
+ <div class="k-chat-user-status">
368
+ <ng-template
369
+ [ngTemplateOutlet]="userStatusTemplate.templateRef"
370
+ [ngTemplateOutletContext]="{ $implicit: group.messages.at(-1) }"
371
+ >
372
+ </ng-template>
373
+ </div>
374
+ }
375
+ </div>
376
+ }
377
+ <div class="k-message-group-content">
378
+ @if (showGroupAuthor(group)) {
379
+ <p class="k-message-author">{{ group.author.name }}</p>
380
+ }
381
+ @for (msg of group.messages; track msg; let firstMessage = $first; let lastMessage = $last) {
382
+ @if (msg.user?.avatarUrl) {
383
+ <div
338
384
  class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
339
- >
385
+ >
340
386
  <span class="k-avatar-image">
341
- <img
342
- [attr.src]="group.author.avatarUrl"
343
- [alt]="group.author.avatarAltText"
344
- />
387
+ <img [src]="msg.user?.avatarUrl">
345
388
  </span>
346
- </div>
347
- <div class="k-chat-user-status-wrapper" *ngIf="userStatusTemplate?.templateRef && showGroupAvatar(group)">
348
- <div
349
- class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
350
- >
351
- <span class="k-avatar-image">
352
- <img
353
- [attr.src]="group.author.avatarUrl"
354
- [alt]="group.author.avatarAltText"
355
- />
356
- </span>
357
- </div>
358
- <div class="k-chat-user-status" *ngIf="userStatusTemplate?.templateRef">
359
- <ng-template
360
- [ngTemplateOutlet]="userStatusTemplate.templateRef"
361
- [ngTemplateOutletContext]="{ $implicit: group.messages.at(-1) }"
362
- >
363
- </ng-template>
364
- </div>
365
- </div>
366
- <div class="k-message-group-content">
367
- <p *ngIf="showGroupAuthor(group)" class="k-message-author">{{ group.author.name }}</p>
368
- <ng-container
369
- *ngFor="let msg of group.messages; first as firstMessage; last as lastMessage"
389
+ </div>
390
+ }
391
+ <kendo-chat-message #message
392
+ [message]="msg"
393
+ [tabbable]="lastGroup && lastMessage"
394
+ [authorMessageContentTemplate]="authorMessageContentTemplate"
395
+ [receiverMessageContentTemplate]="receiverMessageContentTemplate"
396
+ [messageContentTemplate]="messageContentTemplate"
397
+ [authorMessageTemplate]="authorMessageTemplate"
398
+ [receiverMessageTemplate]="receiverMessageTemplate"
399
+ [messageTemplate]="messageTemplate"
400
+ [statusTemplate]="statusTemplate"
401
+ [authorId]="authorId"
402
+ >
403
+ </kendo-chat-message>
404
+ @if (msg.attachments && msg.attachments.length === 1) {
405
+ <kendo-chat-attachment
406
+ [attachment]="msg.attachments[0]"
407
+ [template]="attachmentTemplate"
370
408
  >
371
- <kendo-chat-message #message
372
- [message]="msg"
373
- [tabbable]="lastGroup && lastMessage"
374
- [authorMessageContentTemplate]="authorMessageContentTemplate"
375
- [receiverMessageContentTemplate]="receiverMessageContentTemplate"
376
- [messageContentTemplate]="messageContentTemplate"
377
- [authorMessageTemplate]="authorMessageTemplate"
378
- [receiverMessageTemplate]="receiverMessageTemplate"
379
- [messageTemplate]="messageTemplate"
380
- [statusTemplate]="statusTemplate"
381
- [authorId]="authorId"
382
- >
383
- </kendo-chat-message>
384
-
385
- <kendo-chat-attachment
386
- *ngIf="msg.attachments && msg.attachments.length === 1"
387
- [attachment]="msg.attachments[0]"
388
- [template]="attachmentTemplate"
389
- >
390
- </kendo-chat-attachment>
391
- </ng-container>
392
- </div>
409
+ </kendo-chat-attachment>
410
+ }
411
+ }
393
412
  </div>
394
-
395
- <kendo-chat-message-attachments #attachments
396
- *ngSwitchCase="'attachment-group'"
397
- [attachments]="group.attachments"
398
- [layout]="group.attachmentLayout"
399
- [localization]="localization"
400
- [tabbable]="lastGroup"
401
- [template]="attachmentTemplate"
402
- (click)="select(attachments)"
403
- (focus)="select(attachments)"
413
+ </div>
414
+ }
415
+ @case ('attachment-group') {
416
+ <kendo-chat-message-attachments #attachments
417
+ [attachments]="group.attachments"
418
+ [layout]="group.attachmentLayout"
419
+ [localization]="localization"
420
+ [tabbable]="lastGroup"
421
+ [template]="attachmentTemplate"
422
+ (click)="select(attachments)"
423
+ (focus)="select(attachments)"
404
424
  >
405
- </kendo-chat-message-attachments>
406
-
407
- <kendo-chat-suggested-actions #actions
408
- *ngSwitchCase="'action-group'"
409
- [actions]="group.actions"
410
- type="action"
411
- [tabbable]="lastGroup"
412
- (dispatchAction)="dispatchAction($event, last(view))"
413
- (click)="select(actions, $event)"
414
- (focus)="select(actions, $event)"
425
+ </kendo-chat-message-attachments>
426
+ }
427
+ @case ('action-group') {
428
+ <kendo-chat-suggested-actions #actions
429
+ [actions]="group.actions"
430
+ type="action"
431
+ [tabbable]="lastGroup"
432
+ (dispatchAction)="dispatchAction($event, last(view))"
433
+ (click)="select(actions, $event)"
434
+ (focus)="select(actions, $event)"
415
435
  >
416
- </kendo-chat-suggested-actions>
417
- </ng-container>
418
- </ng-container>
436
+ </kendo-chat-suggested-actions>
437
+ }
438
+ }
439
+ }
419
440
  <kendo-resize-sensor (resize)="onResize()">
420
441
  </kendo-resize-sensor>
421
- `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MessageComponent, selector: "kendo-chat-message", inputs: ["message", "tabbable", "authorMessageContentTemplate", "receiverMessageContentTemplate", "messageContentTemplate", "authorMessageTemplate", "receiverMessageTemplate", "messageTemplate", "statusTemplate", "showMessageTime", "authorId"] }, { kind: "component", type: AttachmentComponent, selector: "kendo-chat-attachment", inputs: ["attachment", "template"] }, { kind: "component", type: MessageAttachmentsComponent, selector: "kendo-chat-message-attachments", inputs: ["attachments", "layout", "tabbable", "template", "localization"] }, { kind: "component", type: SuggestedActionsComponent, selector: "kendo-chat-suggested-actions", inputs: ["actions", "suggestions", "tabbable", "type", "suggestionTemplate"], outputs: ["dispatchAction", "dispatchSuggestion"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }] });
442
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MessageComponent, selector: "kendo-chat-message", inputs: ["message", "tabbable", "authorMessageContentTemplate", "receiverMessageContentTemplate", "messageContentTemplate", "authorMessageTemplate", "receiverMessageTemplate", "messageTemplate", "statusTemplate", "showMessageTime", "authorId"] }, { kind: "component", type: AttachmentComponent, selector: "kendo-chat-attachment", inputs: ["attachment", "template"] }, { kind: "component", type: MessageAttachmentsComponent, selector: "kendo-chat-message-attachments", inputs: ["attachments", "layout", "tabbable", "template", "localization"] }, { kind: "component", type: SuggestedActionsComponent, selector: "kendo-chat-suggested-actions", inputs: ["actions", "suggestions", "tabbable", "type", "suggestionTemplate"], outputs: ["dispatchAction", "dispatchSuggestion"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }] });
422
443
  }
423
444
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageListComponent, decorators: [{
424
445
  type: Component,
425
446
  args: [{
426
447
  selector: 'kendo-chat-message-list',
427
448
  template: `
428
- <ng-container *ngFor="let group of view; last as lastGroup; trackBy: trackGroup">
429
- <ng-container [ngSwitch]="group.type">
430
- <div
431
- *ngSwitchCase="'date-marker'"
432
- class="k-timestamp"
449
+ @for (group of view; track trackGroup($index, group); let lastGroup = $last) {
450
+ @switch (group.type) {
451
+ @case ('date-marker') {
452
+ <div
453
+ class="k-timestamp"
433
454
  >
434
- <ng-container
435
- *ngIf="timestampTemplate?.templateRef"
436
- [ngTemplateOutlet]="timestampTemplate.templateRef"
437
- [ngTemplateOutletContext]="{ $implicit: group.timestamp }"
455
+ @if (timestampTemplate?.templateRef) {
456
+ <ng-container
457
+ [ngTemplateOutlet]="timestampTemplate.templateRef"
458
+ [ngTemplateOutletContext]="{ $implicit: group.timestamp }"
438
459
  >
439
- </ng-container>
440
- <ng-container *ngIf="!timestampTemplate?.templateRef">{{ formatTimeStamp(group.timestamp) }}</ng-container>
441
- </div>
442
- <div
443
- *ngSwitchCase="'message-group'"
444
- class="k-message-group"
445
- [class.k-message-group-sender]="isOwnMessage(group.messages[0])"
446
- [class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
447
- [class.k-no-avatar]="!showGroupAvatar(group)"
448
- [class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
460
+ </ng-container>
461
+ }
462
+ @if (!timestampTemplate?.templateRef) {
463
+ {{ formatTimeStamp(group.timestamp) }}
464
+ }
465
+ </div>
466
+ }
467
+ @case ('message-group') {
468
+ <div
469
+ class="k-message-group"
470
+ [class.k-message-group-sender]="isOwnMessage(group.messages[0])"
471
+ [class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
472
+ [class.k-no-avatar]="!showGroupAvatar(group)"
473
+ [class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
449
474
  >
475
+ @if (!userStatusTemplate?.templateRef && showGroupAvatar(group)) {
476
+ <div
477
+ class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
478
+ >
479
+ <span class="k-avatar-image">
480
+ <img
481
+ [attr.src]="group.author.avatarUrl"
482
+ [alt]="group.author.avatarAltText"
483
+ />
484
+ </span>
485
+ </div>
486
+ }
487
+ @if (showGroupAvatar(group) && userStatusTemplate?.templateRef) {
488
+ <div class="k-chat-user-status-wrapper">
450
489
  <div
451
- *ngIf="!userStatusTemplate?.templateRef && showGroupAvatar(group)"
490
+ class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
491
+ >
492
+ <span class="k-avatar-image">
493
+ <img
494
+ [attr.src]="group.author.avatarUrl"
495
+ [alt]="group.author.avatarAltText"
496
+ />
497
+ </span>
498
+ </div>
499
+ @if (userStatusTemplate?.templateRef) {
500
+ <div class="k-chat-user-status">
501
+ <ng-template
502
+ [ngTemplateOutlet]="userStatusTemplate.templateRef"
503
+ [ngTemplateOutletContext]="{ $implicit: group.messages.at(-1) }"
504
+ >
505
+ </ng-template>
506
+ </div>
507
+ }
508
+ </div>
509
+ }
510
+ <div class="k-message-group-content">
511
+ @if (showGroupAuthor(group)) {
512
+ <p class="k-message-author">{{ group.author.name }}</p>
513
+ }
514
+ @for (msg of group.messages; track msg; let firstMessage = $first; let lastMessage = $last) {
515
+ @if (msg.user?.avatarUrl) {
516
+ <div
452
517
  class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
453
- >
518
+ >
454
519
  <span class="k-avatar-image">
455
- <img
456
- [attr.src]="group.author.avatarUrl"
457
- [alt]="group.author.avatarAltText"
458
- />
520
+ <img [src]="msg.user?.avatarUrl">
459
521
  </span>
460
- </div>
461
- <div class="k-chat-user-status-wrapper" *ngIf="userStatusTemplate?.templateRef && showGroupAvatar(group)">
462
- <div
463
- class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
522
+ </div>
523
+ }
524
+ <kendo-chat-message #message
525
+ [message]="msg"
526
+ [tabbable]="lastGroup && lastMessage"
527
+ [authorMessageContentTemplate]="authorMessageContentTemplate"
528
+ [receiverMessageContentTemplate]="receiverMessageContentTemplate"
529
+ [messageContentTemplate]="messageContentTemplate"
530
+ [authorMessageTemplate]="authorMessageTemplate"
531
+ [receiverMessageTemplate]="receiverMessageTemplate"
532
+ [messageTemplate]="messageTemplate"
533
+ [statusTemplate]="statusTemplate"
534
+ [authorId]="authorId"
535
+ >
536
+ </kendo-chat-message>
537
+ @if (msg.attachments && msg.attachments.length === 1) {
538
+ <kendo-chat-attachment
539
+ [attachment]="msg.attachments[0]"
540
+ [template]="attachmentTemplate"
464
541
  >
465
- <span class="k-avatar-image">
466
- <img
467
- [attr.src]="group.author.avatarUrl"
468
- [alt]="group.author.avatarAltText"
469
- />
470
- </span>
471
- </div>
472
- <div class="k-chat-user-status" *ngIf="userStatusTemplate?.templateRef">
473
- <ng-template
474
- [ngTemplateOutlet]="userStatusTemplate.templateRef"
475
- [ngTemplateOutletContext]="{ $implicit: group.messages.at(-1) }"
476
- >
477
- </ng-template>
478
- </div>
479
- </div>
480
- <div class="k-message-group-content">
481
- <p *ngIf="showGroupAuthor(group)" class="k-message-author">{{ group.author.name }}</p>
482
- <ng-container
483
- *ngFor="let msg of group.messages; first as firstMessage; last as lastMessage"
484
- >
485
- <kendo-chat-message #message
486
- [message]="msg"
487
- [tabbable]="lastGroup && lastMessage"
488
- [authorMessageContentTemplate]="authorMessageContentTemplate"
489
- [receiverMessageContentTemplate]="receiverMessageContentTemplate"
490
- [messageContentTemplate]="messageContentTemplate"
491
- [authorMessageTemplate]="authorMessageTemplate"
492
- [receiverMessageTemplate]="receiverMessageTemplate"
493
- [messageTemplate]="messageTemplate"
494
- [statusTemplate]="statusTemplate"
495
- [authorId]="authorId"
496
- >
497
- </kendo-chat-message>
498
-
499
- <kendo-chat-attachment
500
- *ngIf="msg.attachments && msg.attachments.length === 1"
501
- [attachment]="msg.attachments[0]"
502
- [template]="attachmentTemplate"
503
- >
504
- </kendo-chat-attachment>
505
- </ng-container>
506
- </div>
542
+ </kendo-chat-attachment>
543
+ }
544
+ }
507
545
  </div>
508
-
509
- <kendo-chat-message-attachments #attachments
510
- *ngSwitchCase="'attachment-group'"
511
- [attachments]="group.attachments"
512
- [layout]="group.attachmentLayout"
513
- [localization]="localization"
514
- [tabbable]="lastGroup"
515
- [template]="attachmentTemplate"
516
- (click)="select(attachments)"
517
- (focus)="select(attachments)"
546
+ </div>
547
+ }
548
+ @case ('attachment-group') {
549
+ <kendo-chat-message-attachments #attachments
550
+ [attachments]="group.attachments"
551
+ [layout]="group.attachmentLayout"
552
+ [localization]="localization"
553
+ [tabbable]="lastGroup"
554
+ [template]="attachmentTemplate"
555
+ (click)="select(attachments)"
556
+ (focus)="select(attachments)"
518
557
  >
519
- </kendo-chat-message-attachments>
520
-
521
- <kendo-chat-suggested-actions #actions
522
- *ngSwitchCase="'action-group'"
523
- [actions]="group.actions"
524
- type="action"
525
- [tabbable]="lastGroup"
526
- (dispatchAction)="dispatchAction($event, last(view))"
527
- (click)="select(actions, $event)"
528
- (focus)="select(actions, $event)"
558
+ </kendo-chat-message-attachments>
559
+ }
560
+ @case ('action-group') {
561
+ <kendo-chat-suggested-actions #actions
562
+ [actions]="group.actions"
563
+ type="action"
564
+ [tabbable]="lastGroup"
565
+ (dispatchAction)="dispatchAction($event, last(view))"
566
+ (click)="select(actions, $event)"
567
+ (focus)="select(actions, $event)"
529
568
  >
530
- </kendo-chat-suggested-actions>
531
- </ng-container>
532
- </ng-container>
569
+ </kendo-chat-suggested-actions>
570
+ }
571
+ }
572
+ }
533
573
  <kendo-resize-sensor (resize)="onResize()">
534
574
  </kendo-resize-sensor>
535
- `,
575
+ `,
536
576
  standalone: true,
537
- imports: [NgFor, NgSwitch, NgSwitchCase, NgIf, NgTemplateOutlet, MessageComponent, AttachmentComponent, MessageAttachmentsComponent, SuggestedActionsComponent, ResizeSensorComponent]
577
+ imports: [NgTemplateOutlet, MessageComponent, AttachmentComponent, MessageAttachmentsComponent, SuggestedActionsComponent, ResizeSensorComponent]
538
578
  }]
539
579
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.IntlService }, { type: i0.Renderer2 }, { type: i2.ChatService }, { type: i0.ChangeDetectorRef }], propDecorators: { messages: [{
540
580
  type: Input
@@ -5,7 +5,6 @@
5
5
  /* eslint-disable @typescript-eslint/no-empty-function */
6
6
  import { Component, forwardRef, Input, HostBinding } from '@angular/core';
7
7
  import { ChatItem } from './chat-item';
8
- import { NgIf } from '@angular/common';
9
8
  import { ChatFileComponent } from './chat-file.component';
10
9
  import { ChatService } from './common/chat.service';
11
10
  import { LocalizationService } from '@progress/kendo-angular-l10n';
@@ -34,18 +33,24 @@ export class MessageReferenceComponent extends ChatItem {
34
33
  }
35
34
  focus() { }
36
35
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageReferenceComponent, deps: [{ token: i1.LocalizationService }, { token: i2.ChatService }], target: i0.ɵɵFactoryTarget.Component });
37
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MessageReferenceComponent, isStandalone: true, selector: "chat-message-reference-content", inputs: { message: "message" }, host: { properties: { "class.k-message-reference-content": "this.hostClass" } }, providers: [{
36
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MessageReferenceComponent, isStandalone: true, selector: "chat-message-reference-content", inputs: { message: "message" }, host: { properties: { "class.k-message-reference-content": "this.hostClass" } }, providers: [{
38
37
  provide: ChatItem,
39
38
  useExisting: forwardRef(() => MessageReferenceComponent)
40
39
  }], usesInheritance: true, ngImport: i0, template: `
41
- <ng-container *ngIf="message.text && !message.isDeleted">{{message.text}}</ng-container>
42
- <ng-container *ngIf="!message.text && !message.isDeleted && message.files && message.files.length > 0">
43
- <li class="k-chat-file" [chatFile]="message.files[0]">
44
- </li>
45
- </ng-container>
46
- <ng-container *ngIf="message.isDeleted && isOwnMessage(message)">{{ textFor('deletedMessageSenderText') }}</ng-container>
47
- <ng-container *ngIf="message.isDeleted && !isOwnMessage(message)">{{ textFor('deletedMessageReceiverText') }}</ng-container>
48
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }] });
40
+ @if (message.text && !message.isDeleted) {
41
+ {{message.text}}
42
+ }
43
+ @if (!message.text && !message.isDeleted && message.files && message.files.length > 0) {
44
+ <li class="k-chat-file" [chatFile]="message.files[0]">
45
+ </li>
46
+ }
47
+ @if (message.isDeleted && isOwnMessage(message)) {
48
+ {{ textFor('deletedMessageSenderText') }}
49
+ }
50
+ @if (message.isDeleted && !isOwnMessage(message)) {
51
+ {{ textFor('deletedMessageReceiverText') }}
52
+ }
53
+ `, isInline: true, dependencies: [{ kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }] });
49
54
  }
50
55
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageReferenceComponent, decorators: [{
51
56
  type: Component,
@@ -56,16 +61,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
56
61
  useExisting: forwardRef(() => MessageReferenceComponent)
57
62
  }],
58
63
  template: `
59
- <ng-container *ngIf="message.text && !message.isDeleted">{{message.text}}</ng-container>
60
- <ng-container *ngIf="!message.text && !message.isDeleted && message.files && message.files.length > 0">
61
- <li class="k-chat-file" [chatFile]="message.files[0]">
62
- </li>
63
- </ng-container>
64
- <ng-container *ngIf="message.isDeleted && isOwnMessage(message)">{{ textFor('deletedMessageSenderText') }}</ng-container>
65
- <ng-container *ngIf="message.isDeleted && !isOwnMessage(message)">{{ textFor('deletedMessageReceiverText') }}</ng-container>
66
- `,
64
+ @if (message.text && !message.isDeleted) {
65
+ {{message.text}}
66
+ }
67
+ @if (!message.text && !message.isDeleted && message.files && message.files.length > 0) {
68
+ <li class="k-chat-file" [chatFile]="message.files[0]">
69
+ </li>
70
+ }
71
+ @if (message.isDeleted && isOwnMessage(message)) {
72
+ {{ textFor('deletedMessageSenderText') }}
73
+ }
74
+ @if (message.isDeleted && !isOwnMessage(message)) {
75
+ {{ textFor('deletedMessageReceiverText') }}
76
+ }
77
+ `,
67
78
  standalone: true,
68
- imports: [NgIf, ChatFileComponent]
79
+ imports: [ChatFileComponent]
69
80
  }]
70
81
  }], ctorParameters: () => [{ type: i1.LocalizationService }, { type: i2.ChatService }], propDecorators: { hostClass: [{
71
82
  type: HostBinding,