@progress/kendo-angular-grid 19.3.0-develop.8 → 19.3.0
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/columns/columns-container.d.ts +2 -0
- package/common/data-layout-mode.d.ts +21 -0
- package/common/grid-col-size.d.ts +13 -0
- package/common/provider.service.d.ts +2 -0
- package/common/toolbar-tool-base.directive.d.ts +2 -1
- package/data/data-mapping.service.d.ts +3 -1
- package/directives.d.ts +7 -4
- package/editing/toolbar-editing-tool-base.directive.d.ts +3 -2
- package/editing-directives/editing-directive-base.d.ts +3 -0
- package/editing-directives/in-cell-editing.directive.d.ts +1 -1
- package/editing-directives/reactive-editing.directive.d.ts +1 -1
- package/editing-directives/template-editing.directive.d.ts +1 -1
- package/esm2022/column-menu/column-chooser.component.mjs +1 -1
- package/esm2022/column-menu/column-list.component.mjs +8 -7
- package/esm2022/column-menu/column-menu-item.directive.mjs +1 -1
- package/esm2022/columns/column-base.mjs +4 -4
- package/esm2022/columns/column.component.mjs +1 -1
- package/esm2022/columns/columns-container.mjs +3 -0
- package/esm2022/common/column-info.service.mjs +1 -1
- package/esm2022/common/data-layout-mode.mjs +5 -0
- package/esm2022/common/grid-col-size.mjs +5 -0
- package/esm2022/common/provider.service.mjs +1 -0
- package/esm2022/common/toolbar-tool-base.directive.mjs +6 -2
- package/esm2022/data/data-mapping.service.mjs +14 -3
- package/esm2022/directives.mjs +8 -1
- package/esm2022/editing/toolbar-editing-tool-base.directive.mjs +5 -0
- package/esm2022/editing-directives/editing-directive-base.mjs +17 -2
- package/esm2022/editing-directives/in-cell-editing.directive.mjs +5 -3
- package/esm2022/editing-directives/reactive-editing.directive.mjs +1 -1
- package/esm2022/editing-directives/template-editing.directive.mjs +1 -1
- package/esm2022/filtering/cell/filter-cell-operators.component.mjs +2 -2
- package/esm2022/filtering/filter-row.component.mjs +5 -2
- package/esm2022/filtering/menu/filter-menu-dropdownlist.directive.mjs +1 -1
- package/esm2022/grid.component.mjs +191 -39
- package/esm2022/grid.module.mjs +103 -100
- package/esm2022/grouping/group-header.component.mjs +39 -4
- package/esm2022/grouping/group-panel.component.mjs +13 -8
- package/esm2022/highlight/highlight-item.mjs +5 -0
- package/esm2022/highlight/highlight.directive.mjs +132 -0
- package/esm2022/index.mjs +4 -0
- package/esm2022/localization/messages.mjs +57 -3
- package/esm2022/navigation/navigation-cursor.mjs +7 -1
- package/esm2022/navigation/navigation-metadata.mjs +3 -1
- package/esm2022/navigation/navigation.service.mjs +168 -16
- package/esm2022/navigation/toolbar-tool-name.mjs +2 -1
- package/esm2022/package-metadata.mjs +2 -2
- package/esm2022/pdf/export-element.mjs +14 -5
- package/esm2022/pdf/pdf.component.mjs +3 -1
- package/esm2022/rendering/cell.component.mjs +466 -188
- package/esm2022/rendering/common/col-group.component.mjs +21 -7
- package/esm2022/rendering/details-expand.directive.mjs +5 -2
- package/esm2022/rendering/footer/footer.component.mjs +117 -54
- package/esm2022/rendering/header/header.component.mjs +13 -9
- package/esm2022/rendering/list.component.mjs +19 -12
- package/esm2022/rendering/loading-template.directive.mjs +1 -0
- package/esm2022/rendering/table-body.component.mjs +394 -174
- package/esm2022/rendering/toolbar/tools/ai-assistant/ai-assistant.component.mjs +305 -0
- package/esm2022/rendering/toolbar/tools/ai-assistant/ai-tool.directive.mjs +273 -0
- package/esm2022/rendering/toolbar/tools/ai-assistant/utils.mjs +74 -0
- package/esm2022/rendering/toolbar/tools/column-chooser-tool.directive.mjs +5 -4
- package/esm2022/rendering/toolbar/tools/group-toolbar-tool.component.mjs +11 -9
- package/esm2022/rendering/toolbar/tools/select-all-command-tool.directive.mjs +93 -0
- package/esm2022/row-reordering/row-reorder.service.mjs +2 -2
- package/esm2022/row-reordering/utils.mjs +6 -4
- package/esm2022/selection/cell-selection.service.mjs +6 -3
- package/esm2022/selection/pair-set.mjs +87 -10
- package/esm2022/selection/selection-checkbox.directive.mjs +1 -1
- package/esm2022/selection/selection.directive.mjs +1 -1
- package/fesm2022/progress-kendo-angular-grid.mjs +2583 -639
- package/filtering/filter-row.component.d.ts +1 -0
- package/grid.component.d.ts +29 -1
- package/grid.module.d.ts +102 -99
- package/grouping/group-header.component.d.ts +1 -0
- package/grouping/group-panel.component.d.ts +1 -1
- package/highlight/highlight-item.d.ts +17 -0
- package/highlight/highlight.directive.d.ts +56 -0
- package/index.d.ts +8 -1
- package/localization/messages.d.ts +39 -3
- package/navigation/focus-group.d.ts +1 -1
- package/navigation/navigation-metadata.d.ts +2 -1
- package/navigation/navigation.service.d.ts +6 -0
- package/navigation/toolbar-tool-name.d.ts +1 -0
- package/package.json +22 -21
- package/rendering/cell.component.d.ts +30 -15
- package/rendering/common/col-group.component.d.ts +5 -0
- package/rendering/details-expand.directive.d.ts +5 -2
- package/rendering/footer/footer.component.d.ts +4 -1
- package/rendering/header/header.component.d.ts +1 -0
- package/rendering/list.component.d.ts +4 -1
- package/rendering/loading-template.directive.d.ts +1 -0
- package/rendering/table-body.component.d.ts +3 -1
- package/rendering/toolbar/tools/ai-assistant/ai-assistant.component.d.ts +49 -0
- package/rendering/toolbar/tools/ai-assistant/ai-tool.directive.d.ts +115 -0
- package/rendering/toolbar/tools/ai-assistant/utils.d.ts +131 -0
- package/rendering/toolbar/tools/column-chooser-tool.directive.d.ts +0 -1
- package/rendering/toolbar/tools/select-all-command-tool.directive.d.ts +36 -0
- package/row-reordering/row-reorder.service.d.ts +1 -1
- package/row-reordering/utils.d.ts +1 -1
- package/schematics/ngAdd/index.js +4 -4
- package/selection/cell-selection.service.d.ts +1 -0
- package/selection/pair-set.d.ts +36 -8
- package/selection/selection.directive.d.ts +1 -1
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2025 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { Component, ViewChild } from '@angular/core';
|
|
6
|
+
import { AIPromptComponent, OutputViewComponent, PromptViewComponent, AIPromptCustomMessagesComponent, AIPromptOutputTemplateDirective, AIPromptOutputBodyTemplateDirective } from '@progress/kendo-angular-conversational-ui';
|
|
7
|
+
import { HttpClient, HttpRequest } from '@angular/common/http';
|
|
8
|
+
import { ContextService } from './../../../../common/provider.service';
|
|
9
|
+
import { ColumnInfoService } from './../../../../common/column-info.service';
|
|
10
|
+
import { convertDateStringsInFilter, GridToolbarAIResponseSuccessEvent, GridToolbarAIResponseErrorEvent } from './utils';
|
|
11
|
+
import { NgIf } from '@angular/common';
|
|
12
|
+
import * as i0 from "@angular/core";
|
|
13
|
+
import * as i1 from "@angular/common/http";
|
|
14
|
+
import * as i2 from "./../../../../common/provider.service";
|
|
15
|
+
import * as i3 from "./../../../../common/column-info.service";
|
|
16
|
+
/**
|
|
17
|
+
* @hidden
|
|
18
|
+
*/
|
|
19
|
+
export class AiAssistantComponent {
|
|
20
|
+
http;
|
|
21
|
+
ctx;
|
|
22
|
+
columnInfoService;
|
|
23
|
+
aiPrompt;
|
|
24
|
+
activeView = 0;
|
|
25
|
+
requestUrl;
|
|
26
|
+
requestOptions;
|
|
27
|
+
aiPromptSettings;
|
|
28
|
+
aiToolDirective;
|
|
29
|
+
streaming = false;
|
|
30
|
+
disabledGenerateButton = false;
|
|
31
|
+
lastMessage;
|
|
32
|
+
requestData;
|
|
33
|
+
currentRequestSubscription = null;
|
|
34
|
+
//Remove this when the AI Assistant has a built-in loading indicator
|
|
35
|
+
loadingOutput = { id: 'k-loading-item', output: '', prompt: '' };
|
|
36
|
+
columns = [];
|
|
37
|
+
idCounter = 0;
|
|
38
|
+
constructor(http, ctx, columnInfoService) {
|
|
39
|
+
this.http = http;
|
|
40
|
+
this.ctx = ctx;
|
|
41
|
+
this.columnInfoService = columnInfoService;
|
|
42
|
+
}
|
|
43
|
+
ngAfterViewInit() {
|
|
44
|
+
this.columns = this.columnInfoService.leafNamedColumns.map((col) => ({
|
|
45
|
+
field: col.field,
|
|
46
|
+
title: col.title || col.field
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
ngOnDestroy() {
|
|
50
|
+
this.unsubscribeCurrentRequest();
|
|
51
|
+
}
|
|
52
|
+
message(message) {
|
|
53
|
+
return this.ctx.localization.get(message);
|
|
54
|
+
}
|
|
55
|
+
cancelRequest() {
|
|
56
|
+
this.aiToolDirective.cancelRequest.emit();
|
|
57
|
+
this.unsubscribeCurrentRequest();
|
|
58
|
+
this.streaming = false;
|
|
59
|
+
}
|
|
60
|
+
onPromptRequest(ev) {
|
|
61
|
+
if (this.aiToolDirective.promptOutputs.length === 0) {
|
|
62
|
+
this.aiToolDirective.promptOutputs.push(this.loadingOutput);
|
|
63
|
+
}
|
|
64
|
+
this.unsubscribeCurrentRequest();
|
|
65
|
+
this.streaming = true;
|
|
66
|
+
this.activeView = 1;
|
|
67
|
+
if (ev.prompt) {
|
|
68
|
+
this.lastMessage = ev.prompt;
|
|
69
|
+
}
|
|
70
|
+
this.requestData = {
|
|
71
|
+
columns: this.columns,
|
|
72
|
+
promptMessage: ev.prompt,
|
|
73
|
+
url: this.requestUrl,
|
|
74
|
+
requestOptions: {
|
|
75
|
+
...this.requestOptions
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
if (!this.requestOptions.body) {
|
|
79
|
+
const requestBody = {
|
|
80
|
+
role: this.requestData.requestOptions.role,
|
|
81
|
+
contents: [
|
|
82
|
+
{
|
|
83
|
+
text: this.requestData.promptMessage
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
columns: this.requestData.columns
|
|
87
|
+
};
|
|
88
|
+
this.requestData.requestOptions.body = requestBody;
|
|
89
|
+
}
|
|
90
|
+
this.aiToolDirective.promptRequest.emit({ requestData: this.requestData, isRetry: ev.isRetry });
|
|
91
|
+
if (!this.requestUrl) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
this.currentRequestSubscription = this.sendPromptRequest().subscribe((res) => {
|
|
95
|
+
if (res.body) {
|
|
96
|
+
this.processResponse(res);
|
|
97
|
+
this.streaming = false;
|
|
98
|
+
}
|
|
99
|
+
this.currentRequestSubscription = null;
|
|
100
|
+
}, (error) => {
|
|
101
|
+
this.handleError(error);
|
|
102
|
+
this.streaming = false;
|
|
103
|
+
this.currentRequestSubscription = null;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
sendPromptRequest() {
|
|
107
|
+
const request = new HttpRequest(this.requestData.requestOptions.method, this.requestData.url, this.requestData.requestOptions.body, this.requestData.requestOptions);
|
|
108
|
+
return this.http.request(request);
|
|
109
|
+
}
|
|
110
|
+
processResponse(response) {
|
|
111
|
+
if (this.aiToolDirective.autoClose) {
|
|
112
|
+
this.aiToolDirective.emitOpenClose = true;
|
|
113
|
+
this.aiToolDirective.toggleWindow();
|
|
114
|
+
}
|
|
115
|
+
const responseBody = response.body;
|
|
116
|
+
const responseSuccessEvent = new GridToolbarAIResponseSuccessEvent(response);
|
|
117
|
+
this.aiToolDirective.responseSuccess.emit(responseSuccessEvent);
|
|
118
|
+
if (responseSuccessEvent.isDefaultPrevented()) {
|
|
119
|
+
this.deleteLoadingOutput();
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const isFilterable = Boolean(this.ctx.grid.filterable);
|
|
123
|
+
const isSortable = Boolean(this.ctx.grid.sortable);
|
|
124
|
+
const isGroupable = Boolean(this.ctx.grid.groupable);
|
|
125
|
+
if (isFilterable && responseBody.filter) {
|
|
126
|
+
this.processFilterResponse(responseBody.filter);
|
|
127
|
+
}
|
|
128
|
+
if (isSortable && responseBody.sort) {
|
|
129
|
+
this.processArrayResponse(responseBody.sort, this.ctx.grid.currentState.sort || [], (item) => item.field, (mergedArray) => this.ctx.grid.sortChange.next(mergedArray));
|
|
130
|
+
}
|
|
131
|
+
if (isGroupable && responseBody.group) {
|
|
132
|
+
this.processArrayResponse(responseBody.group, this.ctx.grid.currentState.group || [], (item) => item.field, (mergedArray) => this.ctx.grid.groupChange.next(mergedArray));
|
|
133
|
+
}
|
|
134
|
+
const responseContentStart = [`${this.ctx.localization.get('aiAssistantOutputCardBodyContent')} \n`];
|
|
135
|
+
const responseContentBody = responseBody.messages
|
|
136
|
+
.map((output, idx) => `${idx + 1} ${output}`)
|
|
137
|
+
.join('\n');
|
|
138
|
+
const output = {
|
|
139
|
+
id: this.idCounter++,
|
|
140
|
+
title: this.ctx.localization.get('aiAssistantOutputCardTitle'),
|
|
141
|
+
prompt: this.lastMessage,
|
|
142
|
+
output: responseContentStart.concat(responseContentBody).join(''),
|
|
143
|
+
};
|
|
144
|
+
this.deleteLoadingOutput();
|
|
145
|
+
this.aiToolDirective.promptOutputs.unshift(output);
|
|
146
|
+
}
|
|
147
|
+
handleError(error) {
|
|
148
|
+
const responseErrorEvent = new GridToolbarAIResponseErrorEvent(error);
|
|
149
|
+
this.aiToolDirective.responseError.emit(responseErrorEvent);
|
|
150
|
+
if (responseErrorEvent.isDefaultPrevented()) {
|
|
151
|
+
this.deleteLoadingOutput();
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const output = {
|
|
155
|
+
id: this.idCounter++,
|
|
156
|
+
prompt: this.lastMessage,
|
|
157
|
+
output: error.message
|
|
158
|
+
};
|
|
159
|
+
this.deleteLoadingOutput();
|
|
160
|
+
this.aiToolDirective.promptOutputs.unshift(output);
|
|
161
|
+
}
|
|
162
|
+
deleteLoadingOutput() {
|
|
163
|
+
if (this.aiToolDirective.promptOutputs[0]?.id === this.loadingOutput.id) {
|
|
164
|
+
this.aiToolDirective.promptOutputs.splice(0, 1);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
unsubscribeCurrentRequest() {
|
|
168
|
+
if (this.currentRequestSubscription) {
|
|
169
|
+
this.currentRequestSubscription.unsubscribe();
|
|
170
|
+
this.currentRequestSubscription = null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
processArrayResponse(newItems, currentItems, getField, updateGrid) {
|
|
174
|
+
if (newItems?.length === 0) {
|
|
175
|
+
updateGrid([]);
|
|
176
|
+
}
|
|
177
|
+
else if (newItems?.length) {
|
|
178
|
+
let mergedArray = [...newItems];
|
|
179
|
+
const newFields = newItems.map(getField);
|
|
180
|
+
const existingItemsToKeep = currentItems.filter(item => !newFields.includes(getField(item)));
|
|
181
|
+
mergedArray = [...mergedArray, ...existingItemsToKeep];
|
|
182
|
+
updateGrid(mergedArray);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
processFilterResponse(filter) {
|
|
186
|
+
const processedFilter = convertDateStringsInFilter(filter, this.columnInfoService.leafNamedColumns);
|
|
187
|
+
const clearFilter = Object.keys(processedFilter).length === 0;
|
|
188
|
+
if (clearFilter) {
|
|
189
|
+
this.ctx.grid.filterChange.next(undefined);
|
|
190
|
+
}
|
|
191
|
+
else if (processedFilter?.filters.length) {
|
|
192
|
+
const currentFilter = this.ctx.grid.currentState.filter;
|
|
193
|
+
let mergedFilter = processedFilter;
|
|
194
|
+
if (currentFilter && currentFilter.filters?.length > 0) {
|
|
195
|
+
mergedFilter = {
|
|
196
|
+
logic: 'and',
|
|
197
|
+
filters: [
|
|
198
|
+
currentFilter,
|
|
199
|
+
processedFilter
|
|
200
|
+
]
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
this.ctx.grid.filterChange.next(mergedFilter);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AiAssistantComponent, deps: [{ token: i1.HttpClient }, { token: i2.ContextService }, { token: i3.ColumnInfoService }], target: i0.ɵɵFactoryTarget.Component });
|
|
207
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AiAssistantComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "aiPrompt", first: true, predicate: AIPromptComponent, descendants: true }], ngImport: i0, template: `
|
|
208
|
+
<kendo-aiprompt
|
|
209
|
+
#aiPrompt
|
|
210
|
+
[promptSuggestions]="aiPromptSettings?.promptSuggestions"
|
|
211
|
+
[showOutputRating]="aiPromptSettings?.showOutputRating"
|
|
212
|
+
[streaming]="streaming"
|
|
213
|
+
[speechToTextButton]="aiPromptSettings?.speechToTextButton"
|
|
214
|
+
[(activeView)]="activeView"
|
|
215
|
+
[generateButtonSVGIcon]="aiPromptSettings?.generateButtonSVGIcon"
|
|
216
|
+
[generateButtonIcon]="aiPromptSettings?.generateButtonIcon"
|
|
217
|
+
[disabledGenerateButton]="disabledGenerateButton || promptView.textAreaValue?.length === 0"
|
|
218
|
+
[promptOutputs]="aiPromptSettings?.promptOutputs"
|
|
219
|
+
[textAreaSettings]="aiPromptSettings?.textAreaSettings"
|
|
220
|
+
(promptRequest)="onPromptRequest($event)"
|
|
221
|
+
(promptRequestCancel)="cancelRequest()"
|
|
222
|
+
>
|
|
223
|
+
<kendo-aiprompt-prompt-view #promptView></kendo-aiprompt-prompt-view>
|
|
224
|
+
<kendo-aiprompt-output-view></kendo-aiprompt-output-view>
|
|
225
|
+
<ng-template *ngIf="streaming && aiPrompt.streaming" kendoAIPromptOutputTemplate let-output>
|
|
226
|
+
<div class="k-card">
|
|
227
|
+
<div class="k-card-header">
|
|
228
|
+
<div class="k-card-title">
|
|
229
|
+
<span class="k-skeleton k-skeleton-text k-skeleton-pulse" [style.width.px]="200"></span>
|
|
230
|
+
</div>
|
|
231
|
+
<div class="k-card-subtitle">
|
|
232
|
+
<span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
<div class="k-card-body">
|
|
236
|
+
<span class="k-skeleton k-skeleton-rect k-skeleton-pulse" style="height: 80px;"></span>
|
|
237
|
+
</div>
|
|
238
|
+
<div class="k-card-actions">
|
|
239
|
+
<span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
</ng-template>
|
|
243
|
+
<ng-template *ngIf="!(streaming && aiPrompt.streaming)" kendoAIPromptOutputBodyTemplate let-output>
|
|
244
|
+
<p>{{output.output}}</p>
|
|
245
|
+
</ng-template>
|
|
246
|
+
<kendo-aiprompt-messages
|
|
247
|
+
[generateOutput]="message('aiAssistantApplyButtonText')"
|
|
248
|
+
></kendo-aiprompt-messages>
|
|
249
|
+
</kendo-aiprompt>
|
|
250
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: AIPromptComponent, selector: "kendo-aiprompt", inputs: ["activeView", "promptCommands", "promptSuggestions", "promptOutputs", "showOutputRating", "streaming", "speechToTextButton", "textAreaSettings", "generateButtonSVGIcon", "generateButtonIcon", "disabledGenerateButton"], outputs: ["activeViewChange", "promptRequest", "commandExecute", "outputCopy", "outputRatingChange", "promptRequestCancel"], exportAs: ["kendoAIPrompt"] }, { kind: "component", type: AIPromptCustomMessagesComponent, selector: "kendo-aiprompt-messages" }, { kind: "component", type: PromptViewComponent, selector: "kendo-aiprompt-prompt-view" }, { kind: "component", type: OutputViewComponent, selector: "kendo-aiprompt-output-view" }, { kind: "directive", type: AIPromptOutputTemplateDirective, selector: "[kendoAIPromptOutputTemplate]" }, { kind: "directive", type: AIPromptOutputBodyTemplateDirective, selector: "[kendoAIPromptOutputBodyTemplate]" }] });
|
|
251
|
+
}
|
|
252
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AiAssistantComponent, decorators: [{
|
|
253
|
+
type: Component,
|
|
254
|
+
args: [{
|
|
255
|
+
standalone: true,
|
|
256
|
+
imports: [NgIf, AIPromptComponent, AIPromptCustomMessagesComponent, PromptViewComponent, OutputViewComponent, AIPromptOutputTemplateDirective, AIPromptOutputBodyTemplateDirective],
|
|
257
|
+
template: `
|
|
258
|
+
<kendo-aiprompt
|
|
259
|
+
#aiPrompt
|
|
260
|
+
[promptSuggestions]="aiPromptSettings?.promptSuggestions"
|
|
261
|
+
[showOutputRating]="aiPromptSettings?.showOutputRating"
|
|
262
|
+
[streaming]="streaming"
|
|
263
|
+
[speechToTextButton]="aiPromptSettings?.speechToTextButton"
|
|
264
|
+
[(activeView)]="activeView"
|
|
265
|
+
[generateButtonSVGIcon]="aiPromptSettings?.generateButtonSVGIcon"
|
|
266
|
+
[generateButtonIcon]="aiPromptSettings?.generateButtonIcon"
|
|
267
|
+
[disabledGenerateButton]="disabledGenerateButton || promptView.textAreaValue?.length === 0"
|
|
268
|
+
[promptOutputs]="aiPromptSettings?.promptOutputs"
|
|
269
|
+
[textAreaSettings]="aiPromptSettings?.textAreaSettings"
|
|
270
|
+
(promptRequest)="onPromptRequest($event)"
|
|
271
|
+
(promptRequestCancel)="cancelRequest()"
|
|
272
|
+
>
|
|
273
|
+
<kendo-aiprompt-prompt-view #promptView></kendo-aiprompt-prompt-view>
|
|
274
|
+
<kendo-aiprompt-output-view></kendo-aiprompt-output-view>
|
|
275
|
+
<ng-template *ngIf="streaming && aiPrompt.streaming" kendoAIPromptOutputTemplate let-output>
|
|
276
|
+
<div class="k-card">
|
|
277
|
+
<div class="k-card-header">
|
|
278
|
+
<div class="k-card-title">
|
|
279
|
+
<span class="k-skeleton k-skeleton-text k-skeleton-pulse" [style.width.px]="200"></span>
|
|
280
|
+
</div>
|
|
281
|
+
<div class="k-card-subtitle">
|
|
282
|
+
<span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
<div class="k-card-body">
|
|
286
|
+
<span class="k-skeleton k-skeleton-rect k-skeleton-pulse" style="height: 80px;"></span>
|
|
287
|
+
</div>
|
|
288
|
+
<div class="k-card-actions">
|
|
289
|
+
<span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
|
|
290
|
+
</div>
|
|
291
|
+
</div>
|
|
292
|
+
</ng-template>
|
|
293
|
+
<ng-template *ngIf="!(streaming && aiPrompt.streaming)" kendoAIPromptOutputBodyTemplate let-output>
|
|
294
|
+
<p>{{output.output}}</p>
|
|
295
|
+
</ng-template>
|
|
296
|
+
<kendo-aiprompt-messages
|
|
297
|
+
[generateOutput]="message('aiAssistantApplyButtonText')"
|
|
298
|
+
></kendo-aiprompt-messages>
|
|
299
|
+
</kendo-aiprompt>
|
|
300
|
+
`
|
|
301
|
+
}]
|
|
302
|
+
}], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.ContextService }, { type: i3.ColumnInfoService }]; }, propDecorators: { aiPrompt: [{
|
|
303
|
+
type: ViewChild,
|
|
304
|
+
args: [AIPromptComponent]
|
|
305
|
+
}] } });
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2025 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { Directive, NgZone, ChangeDetectorRef, Input, Output, EventEmitter } from '@angular/core';
|
|
6
|
+
import { RefreshService, ToolBarButtonComponent } from '@progress/kendo-angular-toolbar';
|
|
7
|
+
import { isPresent } from '@progress/kendo-angular-common';
|
|
8
|
+
import { Subscription } from 'rxjs';
|
|
9
|
+
import { sparklesIcon, tableWizardIcon } from '@progress/kendo-svg-icons';
|
|
10
|
+
import { ContextService } from '../../../../common/provider.service';
|
|
11
|
+
import { filter, take } from 'rxjs/operators';
|
|
12
|
+
import { ToolbarToolBase } from '../../../../common/toolbar-tool-base.directive';
|
|
13
|
+
import { ToolbarToolName } from '../../../../navigation/toolbar-tool-name';
|
|
14
|
+
import { WindowService } from '@progress/kendo-angular-dialog';
|
|
15
|
+
import { AiAssistantComponent } from './ai-assistant.component';
|
|
16
|
+
import { DEFAULT_AI_REQUEST_OPTIONS } from './utils';
|
|
17
|
+
import * as i0 from "@angular/core";
|
|
18
|
+
import * as i1 from "@progress/kendo-angular-dialog";
|
|
19
|
+
import * as i2 from "@progress/kendo-angular-toolbar";
|
|
20
|
+
import * as i3 from "../../../../common/provider.service";
|
|
21
|
+
/**
|
|
22
|
+
* Represents an AI Assistant tool of the Grid.
|
|
23
|
+
* Use this directive on any `kendo-toolbar-button` inside a ToolbarComponent in the Grid.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```html-no-run
|
|
27
|
+
* <kendo-grid>
|
|
28
|
+
* <kendo-toolbar>
|
|
29
|
+
* <kendo-toolbar-button kendoGridAIAssistantTool></kendo-toolbar-button>
|
|
30
|
+
* </kendo-toolbar>
|
|
31
|
+
* </kendo-grid>
|
|
32
|
+
* ```
|
|
33
|
+
* @remarks
|
|
34
|
+
* Applied to: {@link ToolBarButtonComponent}.
|
|
35
|
+
*/
|
|
36
|
+
export class AIAssistantToolbarDirective extends ToolbarToolBase {
|
|
37
|
+
windowService;
|
|
38
|
+
host;
|
|
39
|
+
ctx;
|
|
40
|
+
zone;
|
|
41
|
+
refresh;
|
|
42
|
+
/**
|
|
43
|
+
* The URL to which the AI Assistant tool sends the AI request.
|
|
44
|
+
* - When you set this property, the AI Assistant tool sends and handles an HTTP request to the provided `requestUrl`. You can handle the `promptRequest` event to modify the request options before the tool sends it.
|
|
45
|
+
* - When you do not set this property, the AI Assistant tool does not send an HTTP request. You should handle the `promptRequest` event to send and handle a custom HTTP request.
|
|
46
|
+
*/
|
|
47
|
+
requestUrl;
|
|
48
|
+
/**
|
|
49
|
+
* Configures the request options that the AI Assistant tool sends with the AI request.
|
|
50
|
+
*
|
|
51
|
+
* @default { headers: new HttpHeaders({ 'Content-Type': 'application/json' }), role: 'user', method: 'POST', responseType: 'json', withCredentials: false }
|
|
52
|
+
*/
|
|
53
|
+
requestOptions;
|
|
54
|
+
/**
|
|
55
|
+
* Configures the initial settings for the AI Assistant Window when opened.
|
|
56
|
+
*/
|
|
57
|
+
aiWindowSettings;
|
|
58
|
+
/**
|
|
59
|
+
* Configures the initial settings for the AI Prompt component that the AI Assistant Window component uses when opened.
|
|
60
|
+
*/
|
|
61
|
+
aiPromptSettings;
|
|
62
|
+
/**
|
|
63
|
+
* Determines whether to close the AI Assistant Window automatically after a successful request.
|
|
64
|
+
* @default true
|
|
65
|
+
*/
|
|
66
|
+
autoClose = true;
|
|
67
|
+
/**
|
|
68
|
+
* Determines whether to keep the AI Prompt's outputs after closing the AI Assistant Window.
|
|
69
|
+
* @default false
|
|
70
|
+
*/
|
|
71
|
+
keepOutputHistory = false;
|
|
72
|
+
/**
|
|
73
|
+
* Emits an event before the AI Assistant tool sends the AI request.
|
|
74
|
+
* - When you provide a `requestUrl`, you can handle the event to modify the request options.
|
|
75
|
+
* - When you do not provide a `requestUrl`, you can handle the event to perform an entirely custom request.
|
|
76
|
+
*/
|
|
77
|
+
promptRequest = new EventEmitter();
|
|
78
|
+
/**
|
|
79
|
+
* Emits an event when the user clicks the cancel button.
|
|
80
|
+
*/
|
|
81
|
+
cancelRequest = new EventEmitter();
|
|
82
|
+
/**
|
|
83
|
+
* Emits an event when the AI Assistant tool completes the AI request successfully.
|
|
84
|
+
* The event contains the response from the AI service and is preventable to allow stopping the default response handling.
|
|
85
|
+
*/
|
|
86
|
+
responseSuccess = new EventEmitter();
|
|
87
|
+
/**
|
|
88
|
+
* Emits an event when the AI Assistant tool completes the AI request with an error.
|
|
89
|
+
* The event contains the error response from the AI service and is preventable to allow stopping the default error handling.
|
|
90
|
+
*/
|
|
91
|
+
responseError = new EventEmitter();
|
|
92
|
+
/**
|
|
93
|
+
* Emits an event when the AI Assistant tool closes.
|
|
94
|
+
*/
|
|
95
|
+
close = new EventEmitter();
|
|
96
|
+
/**
|
|
97
|
+
* Emits an event when the AI Assistant tool opens.
|
|
98
|
+
*/
|
|
99
|
+
open = new EventEmitter();
|
|
100
|
+
tableWizardIcon = tableWizardIcon;
|
|
101
|
+
emitOpenClose = false;
|
|
102
|
+
promptOutputs = [];
|
|
103
|
+
windowRef;
|
|
104
|
+
subs = new Subscription();
|
|
105
|
+
defaultAiPromptSettings = {
|
|
106
|
+
speechToTextButton: true,
|
|
107
|
+
generateButtonSVGIcon: this.tableWizardIcon,
|
|
108
|
+
generateButtonIcon: 'table-wizard'
|
|
109
|
+
};
|
|
110
|
+
constructor(windowService, host, ctx, zone, refresh, cdr) {
|
|
111
|
+
super(host, ToolbarToolName.aiAssistant, ctx, zone, cdr);
|
|
112
|
+
this.windowService = windowService;
|
|
113
|
+
this.host = host;
|
|
114
|
+
this.ctx = ctx;
|
|
115
|
+
this.zone = zone;
|
|
116
|
+
this.refresh = refresh;
|
|
117
|
+
this.host.rounded = 'full';
|
|
118
|
+
this.host.themeColor = 'primary';
|
|
119
|
+
this.host.showText = 'never';
|
|
120
|
+
}
|
|
121
|
+
ngOnInit() {
|
|
122
|
+
this.subs.add(this.host.click.subscribe(() => this.onClick()));
|
|
123
|
+
const hasToolbarIcon = isPresent(this.host.toolbarOptions.icon) && this.host.toolbarOptions.icon !== '';
|
|
124
|
+
const hasOverflowIcon = isPresent(this.host.overflowOptions.icon) && this.host.overflowOptions.icon !== '';
|
|
125
|
+
const hasIcon = hasToolbarIcon && hasOverflowIcon;
|
|
126
|
+
const hasSvgIcon = isPresent(this.host.toolbarOptions.svgIcon) && isPresent(this.host.overflowOptions.svgIcon);
|
|
127
|
+
if (!hasIcon) {
|
|
128
|
+
this.host.icon = 'sparkles';
|
|
129
|
+
}
|
|
130
|
+
if (!hasSvgIcon) {
|
|
131
|
+
this.host.svgIcon = sparklesIcon;
|
|
132
|
+
}
|
|
133
|
+
this.requestOptions = { ...DEFAULT_AI_REQUEST_OPTIONS, ...this.requestOptions };
|
|
134
|
+
}
|
|
135
|
+
ngAfterViewInit() {
|
|
136
|
+
super.ngAfterViewInit();
|
|
137
|
+
this.zone.onStable.pipe(take(1)).subscribe(() => {
|
|
138
|
+
this.buttonElement?.setAttribute('aria-haspopup', 'dialog');
|
|
139
|
+
this.buttonElement?.setAttribute('aria-expanded', 'false');
|
|
140
|
+
const needsTitle = this.host.showText !== 'always' && this.host.showText !== 'toolbar';
|
|
141
|
+
if (needsTitle && !this.host.title) {
|
|
142
|
+
this.buttonElement?.setAttribute('title', this.ctx.localization.get('aiAssistantToolbarToolText'));
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
this.subs.add(this.refresh.onRefresh.pipe(filter((tool) => tool === this.host)).subscribe((tool) => {
|
|
146
|
+
if (tool.overflows && this.windowRef) {
|
|
147
|
+
this.windowRef.close();
|
|
148
|
+
}
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
151
|
+
ngOnDestroy() {
|
|
152
|
+
super.ngOnDestroy();
|
|
153
|
+
this.subs.unsubscribe();
|
|
154
|
+
this.promptOutputs = [];
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* @hidden
|
|
158
|
+
*/
|
|
159
|
+
onClick() {
|
|
160
|
+
this.emitOpenClose = true;
|
|
161
|
+
this.toggleWindow();
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Toggles the AI Assistant window.
|
|
165
|
+
*/
|
|
166
|
+
toggleWindow() {
|
|
167
|
+
if (!this.windowRef) {
|
|
168
|
+
this.openWindow();
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
this.closeWindow();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
openWindow() {
|
|
175
|
+
if (!this.keepOutputHistory) {
|
|
176
|
+
this.promptOutputs = [];
|
|
177
|
+
}
|
|
178
|
+
const defaultWindowWidth = 437;
|
|
179
|
+
const rtl = this.ctx.localization.rtl;
|
|
180
|
+
const defaultWindowSettings = {
|
|
181
|
+
left: rtl ? this.buttonElement.offsetLeft - (this.aiWindowSettings.width || defaultWindowWidth) : this.buttonElement.offsetLeft + this.buttonElement.offsetWidth,
|
|
182
|
+
top: this.buttonElement.offsetTop + this.buttonElement.offsetHeight,
|
|
183
|
+
width: defaultWindowWidth,
|
|
184
|
+
title: this.ctx.localization.get('aiAssistantWindowTitle'),
|
|
185
|
+
cssClass: 'k-grid-assistant-window',
|
|
186
|
+
content: AiAssistantComponent,
|
|
187
|
+
autoFocusedElement: '.k-input-inner',
|
|
188
|
+
appendTo: this.ctx.grid.windowContainer
|
|
189
|
+
};
|
|
190
|
+
this.aiWindowSettings = {
|
|
191
|
+
...defaultWindowSettings,
|
|
192
|
+
...this.aiWindowSettings
|
|
193
|
+
};
|
|
194
|
+
this.windowRef = this.windowService.open(this.aiWindowSettings);
|
|
195
|
+
this.windowRef.window.instance.messages = {
|
|
196
|
+
closeTitle: this.ctx.localization.get('aiAssistantWindowCloseTitle'),
|
|
197
|
+
maximizeTitle: this.ctx.localization.get('aiAssistantWindowMaximizeTitle'),
|
|
198
|
+
minimizeTitle: this.ctx.localization.get('aiAssistantWindowMinimizeTitle'),
|
|
199
|
+
restoreTitle: this.ctx.localization.get('aiAssistantWindowRestoreTitle')
|
|
200
|
+
};
|
|
201
|
+
const aiPrompt = this.windowRef.content.instance;
|
|
202
|
+
aiPrompt.requestUrl = this.requestUrl;
|
|
203
|
+
aiPrompt.requestOptions = this.requestOptions;
|
|
204
|
+
aiPrompt.aiToolDirective = this;
|
|
205
|
+
aiPrompt.disabledGenerateButton = this.aiPromptSettings?.disabledGenerateButton;
|
|
206
|
+
aiPrompt.streaming = this.aiPromptSettings?.streaming || false;
|
|
207
|
+
aiPrompt.activeView = this.aiPromptSettings?.activeView || 0;
|
|
208
|
+
aiPrompt.aiPromptSettings = { ...this.defaultAiPromptSettings, ...this.aiPromptSettings };
|
|
209
|
+
if (!aiPrompt.aiPromptSettings.promptOutputs) {
|
|
210
|
+
aiPrompt.aiPromptSettings.promptOutputs = this.promptOutputs;
|
|
211
|
+
}
|
|
212
|
+
if (this.emitOpenClose) {
|
|
213
|
+
this.zone.onStable.pipe(take(1)).subscribe(() => {
|
|
214
|
+
const event = {
|
|
215
|
+
aiWindow: this.windowRef.window.instance,
|
|
216
|
+
aiPrompt: this.windowRef.content.instance.aiPrompt
|
|
217
|
+
};
|
|
218
|
+
this.open.emit(event);
|
|
219
|
+
this.emitOpenClose = false;
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
this.subs.add(this.windowRef.window.instance.close.subscribe(() => {
|
|
223
|
+
this.emitOpenClose = true;
|
|
224
|
+
this.closeWindow(true);
|
|
225
|
+
}));
|
|
226
|
+
this.host.selected = true;
|
|
227
|
+
}
|
|
228
|
+
closeWindow(focusAnchor = false) {
|
|
229
|
+
this.windowRef.close();
|
|
230
|
+
if (this.emitOpenClose) {
|
|
231
|
+
this.close.emit();
|
|
232
|
+
this.emitOpenClose = false;
|
|
233
|
+
}
|
|
234
|
+
this.windowRef = null;
|
|
235
|
+
this.buttonElement?.setAttribute('aria-expanded', 'false');
|
|
236
|
+
this.buttonElement?.removeAttribute('aria-controls');
|
|
237
|
+
this.host.selected = false;
|
|
238
|
+
focusAnchor && this.buttonElement?.focus();
|
|
239
|
+
}
|
|
240
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIAssistantToolbarDirective, deps: [{ token: i1.WindowService }, { token: i2.ToolBarButtonComponent }, { token: i3.ContextService }, { token: i0.NgZone }, { token: i2.RefreshService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
241
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: AIAssistantToolbarDirective, isStandalone: true, selector: "[kendoGridAIAssistantTool]", inputs: { requestUrl: "requestUrl", requestOptions: "requestOptions", aiWindowSettings: "aiWindowSettings", aiPromptSettings: "aiPromptSettings", autoClose: "autoClose", keepOutputHistory: "keepOutputHistory" }, outputs: { promptRequest: "promptRequest", cancelRequest: "cancelRequest", responseSuccess: "responseSuccess", responseError: "responseError", close: "close", open: "open" }, usesInheritance: true, ngImport: i0 });
|
|
242
|
+
}
|
|
243
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIAssistantToolbarDirective, decorators: [{
|
|
244
|
+
type: Directive,
|
|
245
|
+
args: [{
|
|
246
|
+
selector: '[kendoGridAIAssistantTool]',
|
|
247
|
+
standalone: true
|
|
248
|
+
}]
|
|
249
|
+
}], ctorParameters: function () { return [{ type: i1.WindowService }, { type: i2.ToolBarButtonComponent }, { type: i3.ContextService }, { type: i0.NgZone }, { type: i2.RefreshService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { requestUrl: [{
|
|
250
|
+
type: Input
|
|
251
|
+
}], requestOptions: [{
|
|
252
|
+
type: Input
|
|
253
|
+
}], aiWindowSettings: [{
|
|
254
|
+
type: Input
|
|
255
|
+
}], aiPromptSettings: [{
|
|
256
|
+
type: Input
|
|
257
|
+
}], autoClose: [{
|
|
258
|
+
type: Input
|
|
259
|
+
}], keepOutputHistory: [{
|
|
260
|
+
type: Input
|
|
261
|
+
}], promptRequest: [{
|
|
262
|
+
type: Output
|
|
263
|
+
}], cancelRequest: [{
|
|
264
|
+
type: Output
|
|
265
|
+
}], responseSuccess: [{
|
|
266
|
+
type: Output
|
|
267
|
+
}], responseError: [{
|
|
268
|
+
type: Output
|
|
269
|
+
}], close: [{
|
|
270
|
+
type: Output
|
|
271
|
+
}], open: [{
|
|
272
|
+
type: Output
|
|
273
|
+
}] } });
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2025 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { HttpHeaders } from "@angular/common/http";
|
|
6
|
+
import { PreventableEvent } from "@progress/kendo-angular-common";
|
|
7
|
+
/**
|
|
8
|
+
* @hidden
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_AI_REQUEST_OPTIONS = {
|
|
11
|
+
headers: new HttpHeaders({
|
|
12
|
+
'Content-Type': 'application/json'
|
|
13
|
+
}),
|
|
14
|
+
role: 'user',
|
|
15
|
+
method: 'POST',
|
|
16
|
+
responseType: 'json'
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* @hidden
|
|
20
|
+
*/
|
|
21
|
+
export const convertDateStringsInFilter = (filter, columns) => {
|
|
22
|
+
if (!filter) {
|
|
23
|
+
return filter;
|
|
24
|
+
}
|
|
25
|
+
if (filter.filters && Array.isArray(filter.filters)) {
|
|
26
|
+
return {
|
|
27
|
+
...filter,
|
|
28
|
+
filters: filter.filters.map(f => convertDateStringsInFilter(f, columns))
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (filter.field && filter.value !== undefined) {
|
|
32
|
+
const column = columns.find(col => col.field === filter.field);
|
|
33
|
+
if (column && isDateField(filter.field, columns)) {
|
|
34
|
+
return {
|
|
35
|
+
...filter,
|
|
36
|
+
value: new Date(filter.value)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return filter;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* @hidden
|
|
44
|
+
*/
|
|
45
|
+
export const isDateField = (fieldName, columns) => {
|
|
46
|
+
const column = columns.find((col) => col.field === fieldName);
|
|
47
|
+
return column?.filter === 'date';
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Represents the event data when the AI Assistant request completes successfully.
|
|
51
|
+
*/
|
|
52
|
+
export class GridToolbarAIResponseSuccessEvent extends PreventableEvent {
|
|
53
|
+
/**
|
|
54
|
+
* The HTTP response from the AI service.
|
|
55
|
+
*/
|
|
56
|
+
response;
|
|
57
|
+
constructor(response) {
|
|
58
|
+
super();
|
|
59
|
+
this.response = response;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Represents the event data when the AI Assistant request completes with an error.
|
|
64
|
+
*/
|
|
65
|
+
export class GridToolbarAIResponseErrorEvent extends PreventableEvent {
|
|
66
|
+
/**
|
|
67
|
+
* The HTTP error response from the AI service.
|
|
68
|
+
*/
|
|
69
|
+
error;
|
|
70
|
+
constructor(error) {
|
|
71
|
+
super();
|
|
72
|
+
this.error = error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -169,7 +169,11 @@ export class ColumnChooserToolbarDirective extends ToolbarToolBase {
|
|
|
169
169
|
this.subs.add(this.popupRef.popup.instance.anchorViewportLeave.subscribe(() => {
|
|
170
170
|
this.closePopup(true);
|
|
171
171
|
}));
|
|
172
|
-
this.subs.add(columnList.apply.subscribe(() => {
|
|
172
|
+
this.subs.add(columnList.apply.subscribe((changed) => {
|
|
173
|
+
if (changed.length) {
|
|
174
|
+
this.cdr.markForCheck();
|
|
175
|
+
this.columnInfoService.changeVisibility(changed);
|
|
176
|
+
}
|
|
173
177
|
this.closePopup();
|
|
174
178
|
}));
|
|
175
179
|
this.zone.runOutsideAngular(() => this.renderer.listen('document', 'click', ({ target }) => {
|
|
@@ -192,9 +196,6 @@ export class ColumnChooserToolbarDirective extends ToolbarToolBase {
|
|
|
192
196
|
this.host.selected = false;
|
|
193
197
|
focusAnchor && this.buttonElement?.focus();
|
|
194
198
|
}
|
|
195
|
-
get buttonElement() {
|
|
196
|
-
return this.host.getButton();
|
|
197
|
-
}
|
|
198
199
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnChooserToolbarDirective, deps: [{ token: i0.Renderer2 }, { token: i1.PopupService }, { token: i2.ToolBarButtonComponent }, { token: i3.ContextService }, { token: i0.NgZone }, { token: i2.RefreshService }, { token: i4.AdaptiveGridService }, { token: i5.ColumnInfoService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
199
200
|
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ColumnChooserToolbarDirective, isStandalone: true, selector: "[kendoGridColumnChooserTool]", inputs: { autoSync: "autoSync", allowHideAll: "allowHideAll" }, usesInheritance: true, ngImport: i0 });
|
|
200
201
|
}
|