@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.
- package/chat/api/action.interface.d.ts +1 -1
- package/chat/api/attachment.interface.d.ts +1 -1
- package/chat/api/chat-file-interface.d.ts +41 -0
- package/chat/api/chat-suggestion.interface.d.ts +25 -0
- package/chat/api/file-action.d.ts +42 -0
- package/chat/api/file-download-event.interface.d.ts +21 -0
- package/chat/api/index.d.ts +8 -0
- package/chat/api/message-action.d.ts +42 -0
- package/{esm2022/chat/chat.directives.mjs → chat/api/message-toolbar-visibility.d.ts} +4 -4
- package/chat/api/message-width-mode.d.ts +10 -0
- package/chat/api/message.interface.d.ts +30 -12
- package/chat/api/send-button-settings.d.ts +15 -0
- package/chat/api/user.interface.d.ts +4 -0
- package/chat/attachment.component.d.ts +1 -1
- package/chat/cards/hero-card.component.d.ts +1 -1
- package/chat/chat-file.component.d.ts +34 -0
- package/chat/chat-item.d.ts +1 -0
- package/chat/chat-view.d.ts +1 -1
- package/chat/chat.component.d.ts +218 -19
- package/chat/chat.module.d.ts +8 -4
- package/chat/common/chat.service.d.ts +51 -0
- package/chat/{chat.directives.d.ts → common/models/default-model-fields.d.ts} +5 -4
- package/chat/common/models/message-box-options.d.ts +1 -1
- package/chat/common/models/model-fields.d.ts +111 -0
- package/chat/common/utils.d.ts +50 -0
- package/chat/l10n/messages.d.ts +40 -3
- package/chat/message-attachments.component.d.ts +1 -4
- package/chat/message-box.component.d.ts +54 -25
- package/chat/message-list.component.d.ts +18 -11
- package/chat/message-reference-content.component.d.ts +24 -0
- package/chat/message.component.d.ts +54 -6
- package/chat/suggested-actions.component.d.ts +17 -4
- package/chat/templates/header-template.directive.d.ts +24 -0
- package/chat/{message-box.directive.d.ts → templates/message-box.directive.d.ts} +1 -1
- package/chat/templates/status-template.directive.d.ts +24 -0
- package/chat/templates/suggestion-template.directive.d.ts +24 -0
- package/chat/templates/timestamp-template.directive.d.ts +28 -0
- package/codemods/template-transformer/index.js +94 -0
- package/codemods/utils.js +609 -0
- package/codemods/v20/chat-user.js +50 -0
- package/conversational-ui.module.d.ts +11 -7
- package/directives.d.ts +9 -5
- package/esm2022/chat/api/chat-file-interface.mjs +5 -0
- package/esm2022/chat/api/chat-suggestion.interface.mjs +5 -0
- package/esm2022/chat/api/file-action.mjs +5 -0
- package/esm2022/chat/api/file-download-event.interface.mjs +5 -0
- package/esm2022/chat/api/index.mjs +8 -0
- package/esm2022/chat/api/message-action.mjs +5 -0
- package/esm2022/chat/api/message-toolbar-visibility.mjs +5 -0
- package/esm2022/chat/api/message-width-mode.mjs +5 -0
- package/esm2022/chat/api/send-button-settings.mjs +5 -0
- package/esm2022/chat/attachment.component.mjs +1 -1
- package/esm2022/chat/builtin-actions.mjs +1 -1
- package/esm2022/chat/cards/hero-card.component.mjs +1 -1
- package/esm2022/chat/chat-file.component.mjs +141 -0
- package/esm2022/chat/chat-item.mjs +1 -0
- package/esm2022/chat/chat-view.mjs +2 -2
- package/esm2022/chat/chat.component.mjs +518 -57
- package/esm2022/chat/chat.module.mjs +8 -4
- package/esm2022/chat/common/chat.service.mjs +97 -0
- package/esm2022/chat/common/models/default-model-fields.mjs +26 -0
- package/esm2022/chat/common/models/model-fields.mjs +5 -0
- package/esm2022/chat/common/utils.mjs +127 -0
- package/esm2022/chat/l10n/messages.mjs +60 -5
- package/esm2022/chat/message-attachments.component.mjs +1 -4
- package/esm2022/chat/message-box.component.mjs +360 -111
- package/esm2022/chat/message-list.component.mjs +166 -96
- package/esm2022/chat/message-reference-content.component.mjs +75 -0
- package/esm2022/chat/message.component.mjs +448 -35
- package/esm2022/chat/suggested-actions.component.mjs +151 -41
- package/esm2022/chat/templates/header-template.directive.mjs +33 -0
- package/esm2022/chat/{message-box.directive.mjs → templates/message-box.directive.mjs} +1 -1
- package/esm2022/chat/templates/status-template.directive.mjs +33 -0
- package/esm2022/chat/templates/suggestion-template.directive.mjs +33 -0
- package/esm2022/chat/templates/timestamp-template.directive.mjs +39 -0
- package/esm2022/conversational-ui.module.mjs +12 -8
- package/esm2022/directives.mjs +12 -4
- package/esm2022/index.mjs +9 -3
- package/esm2022/package-metadata.mjs +2 -2
- package/fesm2022/progress-kendo-angular-conversational-ui.mjs +4986 -3125
- package/index.d.ts +10 -3
- package/package.json +29 -12
- /package/chat/{attachment-template.directive.d.ts → templates/attachment-template.directive.d.ts} +0 -0
- /package/chat/{message-template.directive.d.ts → templates/message-template.directive.d.ts} +0 -0
- /package/esm2022/chat/{attachment-template.directive.mjs → templates/attachment-template.directive.mjs} +0 -0
- /package/esm2022/chat/{message-template.directive.mjs → templates/message-template.directive.mjs} +0 -0
@@ -2,62 +2,104 @@
|
|
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, EventEmitter, HostBinding, Input, Output, ViewChild } from '@angular/core';
|
6
|
-
import { NgIf, NgTemplateOutlet } from '@angular/common';
|
5
|
+
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, Input, Output, Renderer2, ViewChild } from '@angular/core';
|
6
|
+
import { NgIf, NgFor, NgTemplateOutlet } from '@angular/common';
|
7
7
|
import { LocalizationService } from '@progress/kendo-angular-l10n';
|
8
|
-
import { Keys } from '@progress/kendo-angular-common';
|
9
|
-
import { paperPlaneIcon } from '@progress/kendo-svg-icons';
|
10
|
-
import { ButtonComponent } from '@progress/kendo-angular-buttons';
|
8
|
+
import { closest, isPresent, Keys } from '@progress/kendo-angular-common';
|
9
|
+
import { paperPlaneIcon, paperclipIcon, fileIcon, xIcon } from '@progress/kendo-svg-icons';
|
10
|
+
import { ButtonComponent, SpeechToTextButtonComponent } from '@progress/kendo-angular-buttons';
|
11
11
|
import { SendMessageEvent } from './api/post-message-event';
|
12
|
-
import { ChatMessageBoxTemplateDirective } from './message-box.directive';
|
13
|
-
import {
|
12
|
+
import { ChatMessageBoxTemplateDirective } from './templates/message-box.directive';
|
13
|
+
import { InputSpacerComponent, TextAreaComponent, TextAreaPrefixComponent, TextAreaSuffixComponent } from '@progress/kendo-angular-inputs';
|
14
|
+
import { FileSelectComponent } from '@progress/kendo-angular-upload';
|
15
|
+
import { FormsModule } from '@angular/forms';
|
16
|
+
import { ChatService } from './common/chat.service';
|
17
|
+
import { SuggestedActionsComponent } from "./suggested-actions.component";
|
18
|
+
import { Subscription } from 'rxjs';
|
19
|
+
import { ChatFileComponent } from './chat-file.component';
|
20
|
+
import { MessageReferenceComponent } from './message-reference-content.component';
|
21
|
+
import { ChatSuggestionTemplateDirective } from './templates/suggestion-template.directive';
|
14
22
|
import * as i0 from "@angular/core";
|
23
|
+
import * as i1 from "./common/chat.service";
|
15
24
|
/**
|
16
25
|
* @hidden
|
17
26
|
*/
|
18
27
|
export class MessageBoxComponent {
|
28
|
+
chatService;
|
29
|
+
cdr;
|
30
|
+
element;
|
31
|
+
renderer;
|
19
32
|
borderColor = 'inherit';
|
33
|
+
messageBoxWrapperClass = true;
|
20
34
|
messageBoxInput;
|
21
|
-
|
35
|
+
fileSelectComponent;
|
36
|
+
suggestedActionsComponent;
|
37
|
+
authorId;
|
22
38
|
autoScroll;
|
23
|
-
|
39
|
+
suggestions;
|
40
|
+
placeholder;
|
41
|
+
inputValue = '';
|
24
42
|
localization;
|
25
43
|
messageBoxTemplate;
|
44
|
+
suggestionTemplate;
|
26
45
|
sendMessage = new EventEmitter();
|
27
|
-
|
28
|
-
|
29
|
-
|
46
|
+
executeSuggestion = new EventEmitter();
|
47
|
+
fileSelect = new EventEmitter();
|
48
|
+
fileRemove = new EventEmitter();
|
49
|
+
files = [];
|
30
50
|
sendIcon = paperPlaneIcon;
|
31
|
-
|
32
|
-
|
33
|
-
|
51
|
+
attachmentIcon = paperclipIcon;
|
52
|
+
deleteIcon = xIcon;
|
53
|
+
fileIcon = fileIcon;
|
54
|
+
isListening = false;
|
55
|
+
get reply() {
|
56
|
+
return this.chatService.reply;
|
57
|
+
}
|
58
|
+
selectedItem;
|
59
|
+
subs = new Subscription();
|
60
|
+
constructor(chatService, cdr, element, renderer) {
|
61
|
+
this.chatService = chatService;
|
62
|
+
this.cdr = cdr;
|
63
|
+
this.element = element;
|
64
|
+
this.renderer = renderer;
|
65
|
+
}
|
66
|
+
ngOnInit() {
|
67
|
+
const elRef = this.element.nativeElement;
|
68
|
+
this.subs.add(this.renderer.listen(elRef, 'focusout', event => this.onBlur(event)));
|
69
|
+
this.subs.add(this.chatService.contextMenuAction$.subscribe((action) => {
|
70
|
+
action.action.id === 'reply' && this.messageBoxInput.focus();
|
71
|
+
}));
|
72
|
+
}
|
73
|
+
ngOnDestroy() {
|
74
|
+
if (this.subs) {
|
75
|
+
this.subs.unsubscribe();
|
76
|
+
}
|
77
|
+
}
|
34
78
|
sendClick() {
|
35
|
-
const
|
36
|
-
const
|
37
|
-
if (!
|
79
|
+
const hasMessage = this.inputValue?.trim() || this.files?.length;
|
80
|
+
const isCustomDisabled = isPresent(this.sendButtonSettings?.disabled);
|
81
|
+
if (!hasMessage && !isCustomDisabled) {
|
38
82
|
return;
|
39
83
|
}
|
40
84
|
const message = {
|
41
|
-
|
42
|
-
|
43
|
-
|
85
|
+
text: this.inputValue,
|
86
|
+
timestamp: new Date(),
|
87
|
+
author: { id: this.authorId },
|
88
|
+
...(this.files && this.files.length > 0 && { files: this.files }),
|
89
|
+
...(this.reply && { replyToId: this.reply.id })
|
44
90
|
};
|
45
91
|
this.sendMessage.emit(new SendMessageEvent(message));
|
46
|
-
|
47
|
-
|
92
|
+
this.inputValue = '';
|
93
|
+
this.files = [];
|
94
|
+
this.chatService.reply = null;
|
95
|
+
this.messageBoxInput.focus();
|
48
96
|
this.autoScroll = true;
|
49
97
|
}
|
50
|
-
/**
|
51
|
-
* @hidden
|
52
|
-
*/
|
53
98
|
inputKeydown(e) {
|
54
99
|
if (e.code === Keys.Enter || e.code === Keys.NumpadEnter) {
|
55
100
|
this.sendClick();
|
56
101
|
}
|
57
102
|
}
|
58
|
-
/**
|
59
|
-
* @hidden
|
60
|
-
*/
|
61
103
|
textAreaKeydown(e) {
|
62
104
|
const isEnter = e.code === Keys.Enter || e.code === Keys.NumpadEnter;
|
63
105
|
if (!isEnter) {
|
@@ -70,66 +112,197 @@ export class MessageBoxComponent {
|
|
70
112
|
this.sendClick();
|
71
113
|
}
|
72
114
|
if (newLine) {
|
73
|
-
this.
|
115
|
+
this.inputValue += `\r\n`;
|
116
|
+
}
|
117
|
+
}
|
118
|
+
handleSpeechResult(event) {
|
119
|
+
if (event.alternatives && event.alternatives.length > 0) {
|
120
|
+
if (!isPresent(this.inputValue)) {
|
121
|
+
this.inputValue = '';
|
122
|
+
}
|
123
|
+
const appendedValue = event.alternatives[0].transcript + ' ';
|
124
|
+
if (!appendedValue.trim()) {
|
125
|
+
return;
|
126
|
+
}
|
127
|
+
this.inputValue += appendedValue;
|
128
|
+
this.chatService.emit('inputValueChange', this.inputValue);
|
74
129
|
}
|
75
130
|
}
|
76
|
-
/**
|
77
|
-
* @hidden
|
78
|
-
*/
|
79
131
|
textFor(key) {
|
80
132
|
return this.localization.get(key);
|
81
133
|
}
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
134
|
+
removeReply() {
|
135
|
+
this.chatService.reply = null;
|
136
|
+
}
|
137
|
+
onReplyReferenceClick(event) {
|
138
|
+
event.stopPropagation();
|
139
|
+
this.chatService.emit('replyReferenceClick', this.chatService.reply?.id);
|
140
|
+
}
|
141
|
+
handleFileSelect(event) {
|
142
|
+
const processedFiles = event.files.map(currentFile => {
|
143
|
+
return {
|
144
|
+
id: currentFile.uid,
|
145
|
+
name: currentFile.name,
|
146
|
+
extension: currentFile.extension,
|
147
|
+
size: currentFile.size,
|
148
|
+
type: currentFile.rawFile.type,
|
149
|
+
rawFile: currentFile.rawFile
|
150
|
+
};
|
151
|
+
});
|
152
|
+
this.files = [...this.files, ...processedFiles];
|
153
|
+
this.fileSelect.emit(event);
|
154
|
+
}
|
155
|
+
selectFiles() {
|
156
|
+
if (this.fileSelectComponent?.fileSelectInput) {
|
157
|
+
this.fileSelectComponent.fileSelectInput.nativeElement.click();
|
158
|
+
}
|
159
|
+
}
|
160
|
+
removeFile(index) {
|
161
|
+
this.files = this.files.filter((_, i) => i !== index);
|
162
|
+
const removedFile = this.files[index];
|
163
|
+
this.fileRemove.emit(removedFile);
|
164
|
+
}
|
165
|
+
get speechToTextButtonSettings() {
|
166
|
+
return this.chatService.enableSpeechToText;
|
167
|
+
}
|
168
|
+
get sendButtonSettings() {
|
169
|
+
return this.chatService.sendButtonSettings;
|
170
|
+
}
|
171
|
+
get enableFileSelect() {
|
172
|
+
return this.chatService.enableFileSelect;
|
173
|
+
}
|
174
|
+
get isDisabledSendButton() {
|
175
|
+
if (isPresent(this.sendButtonSettings?.disabled)) {
|
176
|
+
return this.sendButtonSettings.disabled;
|
177
|
+
}
|
178
|
+
const isEmptyInput = !this.inputValue?.length || !this.inputValue?.trim();
|
179
|
+
const hasFiles = this.files?.length > 0;
|
180
|
+
return (isEmptyInput && !hasFiles) || this.isListening;
|
181
|
+
}
|
182
|
+
select(item, event) {
|
183
|
+
if (event) {
|
184
|
+
const target = event.target;
|
185
|
+
if (!target.classList.contains('k-suggestion')) {
|
186
|
+
return;
|
187
|
+
}
|
188
|
+
}
|
189
|
+
if (!this.chatService.toggleMessageState) {
|
190
|
+
const prevItem = this.selectedItem;
|
191
|
+
if (prevItem) {
|
192
|
+
prevItem.selected = false;
|
193
|
+
}
|
194
|
+
if (item) {
|
195
|
+
item.selected = true;
|
196
|
+
this.selectedItem = item;
|
197
|
+
}
|
198
|
+
this.cdr.detectChanges();
|
199
|
+
}
|
200
|
+
this.chatService.toggleMessageState = false;
|
201
|
+
}
|
202
|
+
onBlur(args) {
|
203
|
+
const next = args.relatedTarget || document.activeElement;
|
204
|
+
const outside = !closest(next, (node) => node === this.element.nativeElement);
|
205
|
+
if (outside) {
|
206
|
+
this.select(null);
|
207
|
+
}
|
208
|
+
}
|
209
|
+
onInputValueChange(value) {
|
210
|
+
this.inputValue = value;
|
211
|
+
this.chatService.emit('inputValueChange', value);
|
212
|
+
}
|
213
|
+
dispatchSuggestion(suggestion) {
|
214
|
+
this.executeSuggestion.emit(suggestion);
|
215
|
+
}
|
216
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MessageBoxComponent, deps: [{ token: i1.ChatService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
217
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: MessageBoxComponent, isStandalone: true, selector: "kendo-message-box", inputs: { authorId: "authorId", autoScroll: "autoScroll", suggestions: "suggestions", placeholder: "placeholder", inputValue: "inputValue", localization: "localization", messageBoxTemplate: "messageBoxTemplate", suggestionTemplate: "suggestionTemplate" }, outputs: { sendMessage: "sendMessage", executeSuggestion: "executeSuggestion", fileSelect: "fileSelect", fileRemove: "fileRemove" }, host: { properties: { "style.border-color": "this.borderColor", "class.k-message-box-wrapper": "this.messageBoxWrapperClass" } }, viewQueries: [{ propertyName: "messageBoxInput", first: true, predicate: ["messageBoxInput"], descendants: true }, { propertyName: "fileSelectComponent", first: true, predicate: ["fileSelect"], descendants: true }, { propertyName: "suggestedActionsComponent", first: true, predicate: SuggestedActionsComponent, descendants: true }], ngImport: i0, template: `
|
218
|
+
<kendo-chat-suggested-actions
|
219
|
+
*ngIf="suggestions?.length > 0"
|
220
|
+
#suggestedActions
|
221
|
+
[suggestions]="suggestions"
|
222
|
+
[suggestionTemplate]="suggestionTemplate"
|
223
|
+
[tabbable]="true"
|
224
|
+
(dispatchSuggestion)="dispatchSuggestion($event)"
|
225
|
+
(click)="select(suggestedActions, $event)"
|
226
|
+
(focus)="select(suggestedActions, $event)"
|
227
|
+
></kendo-chat-suggested-actions>
|
110
228
|
|
229
|
+
<ng-container *ngIf="!messageBoxTemplate?.templateRef">
|
111
230
|
<kendo-textarea
|
112
|
-
*ngIf="type === 'textarea'"
|
113
231
|
#messageBoxInput
|
114
|
-
class="k-message-box
|
232
|
+
class="k-message-box"
|
115
233
|
resizable="none"
|
116
234
|
[rows]="3"
|
117
235
|
[inputAttributes]="{
|
118
236
|
'aria-label': textFor('messageBoxInputLabel')
|
119
237
|
}"
|
120
|
-
[placeholder]="textFor('messagePlaceholder')"
|
121
|
-
[showSuffixSeparator]="
|
238
|
+
[placeholder]="placeholder || textFor('messagePlaceholder')"
|
239
|
+
[showSuffixSeparator]="false"
|
122
240
|
(keydown)="textAreaKeydown($event)"
|
241
|
+
[value]="inputValue"
|
242
|
+
(valueChange)="onInputValueChange($event)"
|
123
243
|
>
|
244
|
+
<kendo-textarea-prefix *ngIf="reply || (files && files.length > 0)">
|
245
|
+
<div class="k-message-reference k-message-reference-sender" *ngIf="reply" (click)="onReplyReferenceClick($event)">
|
246
|
+
<chat-message-reference-content [message]="reply"></chat-message-reference-content>
|
247
|
+
<span class="k-spacer"></span>
|
248
|
+
<button
|
249
|
+
kendoButton
|
250
|
+
[attr.title]="textFor('removeReplyTitle')"
|
251
|
+
[svgIcon]="deleteIcon"
|
252
|
+
(click)="removeReply()"
|
253
|
+
fillMode="flat"
|
254
|
+
></button>
|
255
|
+
</div>
|
256
|
+
<ul class="k-chat-file-wrapper">
|
257
|
+
<li class="k-chat-file"
|
258
|
+
*ngFor="let file of files; let i = index"
|
259
|
+
[chatFile]="file"
|
260
|
+
[removable]="true"
|
261
|
+
(remove)="removeFile(i)"
|
262
|
+
></li>
|
263
|
+
</ul>
|
264
|
+
</kendo-textarea-prefix>
|
265
|
+
|
124
266
|
<kendo-textarea-suffix>
|
267
|
+
<button *ngIf="speechToTextButtonSettings"
|
268
|
+
kendoSpeechToTextButton
|
269
|
+
[attr.title]="textFor('speechToTextButtonTitle')"
|
270
|
+
[continuous]="speechToTextButtonSettings?.continuous"
|
271
|
+
[disabled]="speechToTextButtonSettings?.disabled"
|
272
|
+
[fillMode]="speechToTextButtonSettings?.fillMode ?? 'clear'"
|
273
|
+
[integrationMode]="speechToTextButtonSettings?.integrationMode ?? 'webSpeech'"
|
274
|
+
[interimResults]="speechToTextButtonSettings?.interimResults"
|
275
|
+
[lang]="speechToTextButtonSettings?.lang"
|
276
|
+
[maxAlternatives]="speechToTextButtonSettings?.maxAlternatives"
|
277
|
+
[rounded]="speechToTextButtonSettings?.rounded"
|
278
|
+
[size]="speechToTextButtonSettings?.size"
|
279
|
+
[themeColor]="speechToTextButtonSettings?.themeColor"
|
280
|
+
(result)="handleSpeechResult($event)"
|
281
|
+
(start)="isListening = true"
|
282
|
+
(end)="isListening = false"
|
283
|
+
></button>
|
125
284
|
<button
|
126
285
|
kendoButton
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
286
|
+
*ngIf="enableFileSelect"
|
287
|
+
[attr.title]="textFor('fileSelectButtonTitle')"
|
288
|
+
[svgIcon]="attachmentIcon"
|
289
|
+
icon="attachment"
|
290
|
+
fillMode="clear"
|
291
|
+
(click)="selectFiles()"
|
292
|
+
></button>
|
293
|
+
<kendo-input-spacer></kendo-input-spacer>
|
294
|
+
<button
|
295
|
+
kendoButton
|
296
|
+
[fillMode]="sendButtonSettings?.fillMode"
|
297
|
+
[themeColor]="sendButtonSettings?.themeColor"
|
298
|
+
[rounded]="sendButtonSettings?.rounded"
|
299
|
+
[class]="sendButtonSettings?.buttonClass || 'k-chat-send'"
|
300
|
+
[icon]="sendButtonSettings?.icon"
|
301
|
+
[svgIcon]="sendButtonSettings?.svgIcon"
|
131
302
|
[tabindex]="0"
|
132
303
|
[attr.title]="textFor('send')"
|
304
|
+
[class.k-disabled]="isDisabledSendButton"
|
305
|
+
[attr.aria-disabled]="isDisabledSendButton"
|
133
306
|
(click)="sendClick()"
|
134
307
|
>
|
135
308
|
</button>
|
@@ -137,63 +310,110 @@ export class MessageBoxComponent {
|
|
137
310
|
</kendo-textarea>
|
138
311
|
</ng-container>
|
139
312
|
|
140
|
-
<ng-template *ngIf="messageBoxTemplate" [ngTemplateOutlet]="messageBoxTemplate?.templateRef"></ng-template>
|
141
|
-
|
313
|
+
<ng-template *ngIf="messageBoxTemplate?.templateRef" [ngTemplateOutlet]="messageBoxTemplate?.templateRef"></ng-template>
|
314
|
+
|
315
|
+
<kendo-fileselect
|
316
|
+
#fileSelect
|
317
|
+
class="k-hidden"
|
318
|
+
[multiple]="true"
|
319
|
+
[showFileList]="false"
|
320
|
+
(select)="handleFileSelect($event)"
|
321
|
+
></kendo-fileselect>
|
322
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: 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: "ngmodule", type: FormsModule }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }, { kind: "component", type: TextAreaSuffixComponent, selector: "kendo-textarea-suffix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaSuffix"] }, { kind: "component", type: TextAreaPrefixComponent, selector: "kendo-textarea-prefix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaPrefix"] }, { kind: "component", type: SpeechToTextButtonComponent, selector: "button[kendoSpeechToTextButton]", inputs: ["disabled", "size", "rounded", "fillMode", "themeColor", "integrationMode", "lang", "continuous", "interimResults", "maxAlternatives"], outputs: ["start", "end", "result", "error", "click"], exportAs: ["kendoSpeechToTextButton"] }, { kind: "component", type: InputSpacerComponent, selector: "kendo-input-spacer, kendo-textbox-spacer", inputs: ["width"] }, { kind: "component", type: FileSelectComponent, selector: "kendo-fileselect", inputs: ["name"], outputs: ["valueChange"], exportAs: ["kendoFileSelect"] }, { kind: "component", type: SuggestedActionsComponent, selector: "kendo-chat-suggested-actions", inputs: ["actions", "suggestions", "tabbable", "suggestionTemplate"], outputs: ["dispatchAction", "dispatchSuggestion"] }, { kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }] });
|
142
323
|
}
|
143
324
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MessageBoxComponent, decorators: [{
|
144
325
|
type: Component,
|
145
326
|
args: [{
|
146
327
|
selector: 'kendo-message-box',
|
147
328
|
template: `
|
148
|
-
<
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
>
|
159
|
-
<ng-template kendoTextBoxSuffixTemplate>
|
160
|
-
<kendo-textbox-separator></kendo-textbox-separator>
|
161
|
-
<button
|
162
|
-
kendoButton
|
163
|
-
fillMode="flat"
|
164
|
-
class="k-chat-send"
|
165
|
-
icon="paper-plane"
|
166
|
-
[svgIcon]="sendIcon"
|
167
|
-
[tabindex]="0"
|
168
|
-
[attr.title]="textFor('send')"
|
169
|
-
(click)="sendClick()"
|
170
|
-
>
|
171
|
-
</button>
|
172
|
-
</ng-template>
|
173
|
-
</kendo-textbox>
|
329
|
+
<kendo-chat-suggested-actions
|
330
|
+
*ngIf="suggestions?.length > 0"
|
331
|
+
#suggestedActions
|
332
|
+
[suggestions]="suggestions"
|
333
|
+
[suggestionTemplate]="suggestionTemplate"
|
334
|
+
[tabbable]="true"
|
335
|
+
(dispatchSuggestion)="dispatchSuggestion($event)"
|
336
|
+
(click)="select(suggestedActions, $event)"
|
337
|
+
(focus)="select(suggestedActions, $event)"
|
338
|
+
></kendo-chat-suggested-actions>
|
174
339
|
|
340
|
+
<ng-container *ngIf="!messageBoxTemplate?.templateRef">
|
175
341
|
<kendo-textarea
|
176
|
-
*ngIf="type === 'textarea'"
|
177
342
|
#messageBoxInput
|
178
|
-
class="k-message-box
|
343
|
+
class="k-message-box"
|
179
344
|
resizable="none"
|
180
345
|
[rows]="3"
|
181
346
|
[inputAttributes]="{
|
182
347
|
'aria-label': textFor('messageBoxInputLabel')
|
183
348
|
}"
|
184
|
-
[placeholder]="textFor('messagePlaceholder')"
|
185
|
-
[showSuffixSeparator]="
|
349
|
+
[placeholder]="placeholder || textFor('messagePlaceholder')"
|
350
|
+
[showSuffixSeparator]="false"
|
186
351
|
(keydown)="textAreaKeydown($event)"
|
352
|
+
[value]="inputValue"
|
353
|
+
(valueChange)="onInputValueChange($event)"
|
187
354
|
>
|
355
|
+
<kendo-textarea-prefix *ngIf="reply || (files && files.length > 0)">
|
356
|
+
<div class="k-message-reference k-message-reference-sender" *ngIf="reply" (click)="onReplyReferenceClick($event)">
|
357
|
+
<chat-message-reference-content [message]="reply"></chat-message-reference-content>
|
358
|
+
<span class="k-spacer"></span>
|
359
|
+
<button
|
360
|
+
kendoButton
|
361
|
+
[attr.title]="textFor('removeReplyTitle')"
|
362
|
+
[svgIcon]="deleteIcon"
|
363
|
+
(click)="removeReply()"
|
364
|
+
fillMode="flat"
|
365
|
+
></button>
|
366
|
+
</div>
|
367
|
+
<ul class="k-chat-file-wrapper">
|
368
|
+
<li class="k-chat-file"
|
369
|
+
*ngFor="let file of files; let i = index"
|
370
|
+
[chatFile]="file"
|
371
|
+
[removable]="true"
|
372
|
+
(remove)="removeFile(i)"
|
373
|
+
></li>
|
374
|
+
</ul>
|
375
|
+
</kendo-textarea-prefix>
|
376
|
+
|
188
377
|
<kendo-textarea-suffix>
|
378
|
+
<button *ngIf="speechToTextButtonSettings"
|
379
|
+
kendoSpeechToTextButton
|
380
|
+
[attr.title]="textFor('speechToTextButtonTitle')"
|
381
|
+
[continuous]="speechToTextButtonSettings?.continuous"
|
382
|
+
[disabled]="speechToTextButtonSettings?.disabled"
|
383
|
+
[fillMode]="speechToTextButtonSettings?.fillMode ?? 'clear'"
|
384
|
+
[integrationMode]="speechToTextButtonSettings?.integrationMode ?? 'webSpeech'"
|
385
|
+
[interimResults]="speechToTextButtonSettings?.interimResults"
|
386
|
+
[lang]="speechToTextButtonSettings?.lang"
|
387
|
+
[maxAlternatives]="speechToTextButtonSettings?.maxAlternatives"
|
388
|
+
[rounded]="speechToTextButtonSettings?.rounded"
|
389
|
+
[size]="speechToTextButtonSettings?.size"
|
390
|
+
[themeColor]="speechToTextButtonSettings?.themeColor"
|
391
|
+
(result)="handleSpeechResult($event)"
|
392
|
+
(start)="isListening = true"
|
393
|
+
(end)="isListening = false"
|
394
|
+
></button>
|
189
395
|
<button
|
190
396
|
kendoButton
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
397
|
+
*ngIf="enableFileSelect"
|
398
|
+
[attr.title]="textFor('fileSelectButtonTitle')"
|
399
|
+
[svgIcon]="attachmentIcon"
|
400
|
+
icon="attachment"
|
401
|
+
fillMode="clear"
|
402
|
+
(click)="selectFiles()"
|
403
|
+
></button>
|
404
|
+
<kendo-input-spacer></kendo-input-spacer>
|
405
|
+
<button
|
406
|
+
kendoButton
|
407
|
+
[fillMode]="sendButtonSettings?.fillMode"
|
408
|
+
[themeColor]="sendButtonSettings?.themeColor"
|
409
|
+
[rounded]="sendButtonSettings?.rounded"
|
410
|
+
[class]="sendButtonSettings?.buttonClass || 'k-chat-send'"
|
411
|
+
[icon]="sendButtonSettings?.icon"
|
412
|
+
[svgIcon]="sendButtonSettings?.svgIcon"
|
195
413
|
[tabindex]="0"
|
196
414
|
[attr.title]="textFor('send')"
|
415
|
+
[class.k-disabled]="isDisabledSendButton"
|
416
|
+
[attr.aria-disabled]="isDisabledSendButton"
|
197
417
|
(click)="sendClick()"
|
198
418
|
>
|
199
419
|
</button>
|
@@ -201,27 +421,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
201
421
|
</kendo-textarea>
|
202
422
|
</ng-container>
|
203
423
|
|
204
|
-
<ng-template *ngIf="messageBoxTemplate" [ngTemplateOutlet]="messageBoxTemplate?.templateRef"></ng-template>
|
424
|
+
<ng-template *ngIf="messageBoxTemplate?.templateRef" [ngTemplateOutlet]="messageBoxTemplate?.templateRef"></ng-template>
|
425
|
+
|
426
|
+
<kendo-fileselect
|
427
|
+
#fileSelect
|
428
|
+
class="k-hidden"
|
429
|
+
[multiple]="true"
|
430
|
+
[showFileList]="false"
|
431
|
+
(select)="handleFileSelect($event)"
|
432
|
+
></kendo-fileselect>
|
205
433
|
`,
|
206
434
|
standalone: true,
|
207
|
-
imports: [NgIf, ButtonComponent,
|
435
|
+
imports: [NgIf, NgFor, ButtonComponent, FormsModule, NgTemplateOutlet, TextAreaComponent, MessageReferenceComponent, TextAreaSuffixComponent, TextAreaPrefixComponent, SpeechToTextButtonComponent, InputSpacerComponent, FileSelectComponent, SuggestedActionsComponent, ChatFileComponent]
|
208
436
|
}]
|
209
|
-
}], propDecorators: { borderColor: [{
|
437
|
+
}], ctorParameters: function () { return [{ type: i1.ChatService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { borderColor: [{
|
210
438
|
type: HostBinding,
|
211
439
|
args: ['style.border-color']
|
440
|
+
}], messageBoxWrapperClass: [{
|
441
|
+
type: HostBinding,
|
442
|
+
args: ['class.k-message-box-wrapper']
|
212
443
|
}], messageBoxInput: [{
|
213
444
|
type: ViewChild,
|
214
|
-
args: ['messageBoxInput'
|
215
|
-
}],
|
445
|
+
args: ['messageBoxInput']
|
446
|
+
}], fileSelectComponent: [{
|
447
|
+
type: ViewChild,
|
448
|
+
args: ['fileSelect']
|
449
|
+
}], suggestedActionsComponent: [{
|
450
|
+
type: ViewChild,
|
451
|
+
args: [SuggestedActionsComponent]
|
452
|
+
}], authorId: [{
|
216
453
|
type: Input
|
217
454
|
}], autoScroll: [{
|
218
455
|
type: Input
|
219
|
-
}],
|
456
|
+
}], suggestions: [{
|
457
|
+
type: Input
|
458
|
+
}], placeholder: [{
|
459
|
+
type: Input
|
460
|
+
}], inputValue: [{
|
220
461
|
type: Input
|
221
462
|
}], localization: [{
|
222
463
|
type: Input
|
223
464
|
}], messageBoxTemplate: [{
|
224
465
|
type: Input
|
466
|
+
}], suggestionTemplate: [{
|
467
|
+
type: Input
|
225
468
|
}], sendMessage: [{
|
226
469
|
type: Output
|
470
|
+
}], executeSuggestion: [{
|
471
|
+
type: Output
|
472
|
+
}], fileSelect: [{
|
473
|
+
type: Output
|
474
|
+
}], fileRemove: [{
|
475
|
+
type: Output
|
227
476
|
}] } });
|