@progress/kendo-angular-grid 20.1.0-develop.24 → 20.1.0-develop.25

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.
@@ -6,11 +6,11 @@ import * as i0 from '@angular/core';
6
6
  import { EventEmitter, Injectable, SecurityContext, InjectionToken, Optional, Inject, Directive, SkipSelf, Input, isDevMode, QueryList, Component, ContentChildren, ContentChild, forwardRef, Host, Output, HostBinding, Pipe, TemplateRef, ChangeDetectionStrategy, ViewChildren, ViewChild, Self, NgZone, HostListener, ElementRef, ViewContainerRef, ViewEncapsulation, inject, Injector, NgModule } from '@angular/core';
7
7
  import { merge, of, Subject, zip as zip$1, from, Subscription, interval, fromEvent, Observable, BehaviorSubject } from 'rxjs';
8
8
  import * as i1$3 from '@progress/kendo-angular-common';
9
- import { isDocumentAvailable, Keys, hasClasses as hasClasses$1, isPresent as isPresent$1, normalizeNumpadKeys, anyChanged, TemplateContextDirective, DraggableDirective, EventsOutsideAngularDirective, replaceMessagePlaceholder, isChanged as isChanged$1, KendoInput, guid, areObjectsEqual, PrefixTemplateDirective, closest as closest$1, hasObservers, ResizeSensorComponent, isFirefox, firefoxMaxHeight, closestInScope as closestInScope$1, isFocusable as isFocusable$1, PreventableEvent as PreventableEvent$1, getLicenseMessage, shouldShowValidationUI, WatermarkOverlayComponent, ResizeBatchService } from '@progress/kendo-angular-common';
9
+ import { isDocumentAvailable, Keys, hasClasses as hasClasses$1, isPresent as isPresent$1, normalizeNumpadKeys, anyChanged, TemplateContextDirective, DraggableDirective, EventsOutsideAngularDirective, replaceMessagePlaceholder, isChanged as isChanged$1, KendoInput, guid, areObjectsEqual, PrefixTemplateDirective, closest as closest$1, hasObservers, ResizeSensorComponent, isFirefox, firefoxMaxHeight, closestInScope as closestInScope$1, isFocusable as isFocusable$1, getLicenseMessage, shouldShowValidationUI, WatermarkOverlayComponent, PreventableEvent as PreventableEvent$1, ResizeBatchService } from '@progress/kendo-angular-common';
10
10
  import * as i1 from '@angular/platform-browser';
11
11
  import * as i1$1 from '@progress/kendo-angular-icons';
12
12
  import { IconWrapperComponent, IconsService, KENDO_ICONS } from '@progress/kendo-angular-icons';
13
- import { plusIcon, cancelIcon, lockIcon, unlockIcon, caretAltDownIcon, caretAltRightIcon, caretAltLeftIcon, arrowLeftIcon, arrowRightIcon, sortDescSmallIcon, sortAscSmallIcon, filterClearIcon, filterIcon, searchIcon, checkIcon, arrowRotateCcwIcon, columnsIcon, pencilIcon, saveIcon, trashIcon, fileExcelIcon, filePdfIcon, sparklesIcon, chevronUpIcon, chevronDownIcon, chevronRightIcon, displayInlineFlexIcon, maxWidthIcon, stickIcon, unstickIcon, setColumnPositionIcon, slidersIcon, moreVerticalIcon, reorderIcon, minusIcon, insertMiddleIcon, xIcon, xCircleIcon, plusCircleIcon, chevronLeftIcon, tableWizardIcon, undoIcon, redoIcon, arrowsSwapIcon, groupIcon } from '@progress/kendo-svg-icons';
13
+ import { plusIcon, cancelIcon, lockIcon, unlockIcon, caretAltDownIcon, caretAltRightIcon, caretAltLeftIcon, arrowLeftIcon, arrowRightIcon, sortDescSmallIcon, sortAscSmallIcon, filterClearIcon, filterIcon, searchIcon, checkIcon, arrowRotateCcwIcon, columnsIcon, pencilIcon, saveIcon, trashIcon, fileExcelIcon, filePdfIcon, sparklesIcon, chevronUpIcon, chevronDownIcon, chevronRightIcon, displayInlineFlexIcon, maxWidthIcon, stickIcon, unstickIcon, setColumnPositionIcon, slidersIcon, moreVerticalIcon, reorderIcon, minusIcon, insertMiddleIcon, xIcon, xCircleIcon, plusCircleIcon, chevronLeftIcon, undoIcon, redoIcon, arrowsSwapIcon, groupIcon, tableWizardIcon } from '@progress/kendo-svg-icons';
14
14
  import { switchMap, take, map, filter, takeUntil, switchMapTo, delay, tap, throttleTime, debounceTime, distinctUntilChanged, skip, auditTime, bufferCount, flatMap } from 'rxjs/operators';
15
15
  import * as i1$2 from '@progress/kendo-angular-l10n';
16
16
  import { ComponentMessages, LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
@@ -22812,8 +22812,8 @@ const packageMetadata = {
22812
22812
  productName: 'Kendo UI for Angular',
22813
22813
  productCode: 'KENDOUIANGULAR',
22814
22814
  productCodes: ['KENDOUIANGULAR'],
22815
- publishDate: 1760339667,
22816
- version: '20.1.0-develop.24',
22815
+ publishDate: 1760349490,
22816
+ version: '20.1.0-develop.25',
22817
22817
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
22818
22818
  };
22819
22819
 
@@ -29623,684 +29623,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
29623
29623
  args: [GroupToolbarToolComponent]
29624
29624
  }] } });
29625
29625
 
29626
- /**
29627
- * @hidden
29628
- */
29629
- const DEFAULT_AI_REQUEST_OPTIONS = {
29630
- headers: new HttpHeaders({
29631
- 'Content-Type': 'application/json'
29632
- }),
29633
- role: 'user',
29634
- method: 'POST',
29635
- responseType: 'json'
29636
- };
29637
- /**
29638
- * Represents the event data when the AI Assistant request completes successfully.
29639
- */
29640
- class GridToolbarAIResponseSuccessEvent extends PreventableEvent$1 {
29641
- /**
29642
- * The HTTP response from the AI service.
29643
- */
29644
- response;
29645
- constructor(response) {
29646
- super();
29647
- this.response = response;
29648
- }
29649
- }
29650
- /**
29651
- * Represents the event data when the AI Assistant request completes with an error.
29652
- */
29653
- class GridToolbarAIResponseErrorEvent extends PreventableEvent$1 {
29654
- /**
29655
- * The HTTP error response from the AI service.
29656
- */
29657
- error;
29658
- constructor(error) {
29659
- super();
29660
- this.error = error;
29661
- }
29662
- }
29663
-
29664
- /**
29665
- * @hidden
29666
- * Converts date strings in a filter to Date objects.
29667
- */
29668
- const convertDateStringsInFilter = (filter) => {
29669
- if (!filter) {
29670
- return filter;
29671
- }
29672
- if (filter.filters && Array.isArray(filter.filters)) {
29673
- return {
29674
- ...filter,
29675
- filters: filter.filters.map(f => convertDateStringsInFilter(f))
29676
- };
29677
- }
29678
- if (filter.field && filter.value !== undefined) {
29679
- if (typeof filter.value === 'string' && isDateOperator(filter.operator)) {
29680
- const date = parseDate(filter.value);
29681
- return {
29682
- ...filter,
29683
- value: date || filter.value
29684
- };
29685
- }
29686
- }
29687
- return filter;
29688
- };
29689
- /**
29690
- * @hidden
29691
- */
29692
- const isDateOperator = (operator) => {
29693
- const dateOperators = [
29694
- 'eq', 'neq', 'lt', 'lte', 'gt', 'gte'
29695
- ];
29696
- return dateOperators.includes(operator);
29697
- };
29698
- /**
29699
- * @hidden
29700
- * Processes cell highlights for a specific filter and item.
29701
- */
29702
- const processCellHighlights = (filter, rowIndex, columns, highlightItems) => {
29703
- Object.keys(filter.cells).forEach((columnField) => {
29704
- const actualColumnIndex = Array.from(columns).findIndex((col) => col.field === columnField);
29705
- if (actualColumnIndex !== -1) {
29706
- highlightItems.push({
29707
- itemKey: rowIndex,
29708
- columnKey: actualColumnIndex,
29709
- });
29710
- }
29711
- });
29712
- };
29713
- /**
29714
- * @hidden
29715
- * Processes filtered results and adds highlight items.
29716
- */
29717
- const processFilteredResults = (filteredResults, data, filter, columns, highlightItems) => {
29718
- filteredResults?.forEach((item) => {
29719
- const rowIndex = data.findIndex((dataItem) => dataItem === item);
29720
- if (filter.cells && Object.keys(filter.cells).length > 0) {
29721
- processCellHighlights(filter, rowIndex, columns, highlightItems);
29722
- }
29723
- else {
29724
- highlightItems.push({
29725
- itemKey: rowIndex,
29726
- });
29727
- }
29728
- });
29729
- };
29730
- /**
29731
- * @hidden
29732
- * Highlights items in a grid based on the provided filters and columns.
29733
- * @param data - The data to be highlighted.
29734
- * @param filters - The composite highlight descriptors containing the filters and logic.
29735
- * @param columns - The columns of the grid.
29736
- * @returns An array of HighlightItem objects representing the highlighted items.
29737
- */
29738
- const highlightBy = (data, filters, columns) => {
29739
- const highlightItems = [];
29740
- filters.forEach((filter) => {
29741
- const processedFilters = filter.filters.map((filter) => convertDateStringsInFilter(filter));
29742
- const filteredResults = filterBy(data, {
29743
- logic: filter.logic || "and",
29744
- filters: processedFilters,
29745
- });
29746
- processFilteredResults(filteredResults, data, filter, columns, highlightItems);
29747
- });
29748
- return highlightItems;
29749
- };
29750
-
29751
- /**
29752
- * @hidden
29753
- */
29754
- class AiAssistantComponent {
29755
- http;
29756
- ctx;
29757
- columnInfoService;
29758
- aiPrompt;
29759
- activeView = 0;
29760
- requestUrl;
29761
- requestOptions;
29762
- aiPromptSettings;
29763
- aiToolDirective;
29764
- streaming = false;
29765
- disabledGenerateButton = false;
29766
- lastMessage;
29767
- requestData;
29768
- currentRequestSubscription = null;
29769
- //Remove this when the AI Assistant has a built-in loading indicator
29770
- loadingOutput = { id: 'k-loading-item', output: '', prompt: '' };
29771
- columns = [];
29772
- idCounter = 0;
29773
- constructor(http, ctx, columnInfoService) {
29774
- this.http = http;
29775
- this.ctx = ctx;
29776
- this.columnInfoService = columnInfoService;
29777
- }
29778
- ngAfterViewInit() {
29779
- this.columns = this.columnInfoService.leafNamedColumns.map((col) => ({ field: col.field }));
29780
- }
29781
- ngOnDestroy() {
29782
- this.unsubscribeCurrentRequest();
29783
- }
29784
- message(message) {
29785
- return this.ctx.localization.get(message);
29786
- }
29787
- cancelRequest() {
29788
- this.aiToolDirective.cancelRequest.emit();
29789
- this.unsubscribeCurrentRequest();
29790
- this.streaming = false;
29791
- }
29792
- onPromptRequest(ev) {
29793
- if (this.aiToolDirective.promptOutputs.length === 0) {
29794
- this.aiToolDirective.promptOutputs.push(this.loadingOutput);
29795
- }
29796
- this.unsubscribeCurrentRequest();
29797
- this.streaming = true;
29798
- this.activeView = 1;
29799
- if (ev.prompt) {
29800
- this.lastMessage = ev.prompt;
29801
- }
29802
- this.requestData = {
29803
- columns: this.columns,
29804
- promptMessage: ev.prompt,
29805
- url: this.requestUrl,
29806
- requestOptions: {
29807
- ...this.requestOptions
29808
- }
29809
- };
29810
- if (!this.requestOptions.body) {
29811
- const requestBody = {
29812
- role: this.requestData.requestOptions.role,
29813
- contents: [
29814
- {
29815
- text: this.requestData.promptMessage
29816
- }
29817
- ],
29818
- columns: this.requestData.columns
29819
- };
29820
- this.requestData.requestOptions.body = requestBody;
29821
- }
29822
- this.aiToolDirective.promptRequest.emit({ requestData: this.requestData, isRetry: ev.isRetry });
29823
- if (!this.requestUrl) {
29824
- return;
29825
- }
29826
- this.currentRequestSubscription = this.sendPromptRequest().subscribe((res) => {
29827
- if (res.body) {
29828
- this.processResponse(res);
29829
- this.streaming = false;
29830
- }
29831
- this.currentRequestSubscription = null;
29832
- }, (error) => {
29833
- this.handleError(error);
29834
- this.streaming = false;
29835
- this.currentRequestSubscription = null;
29836
- });
29837
- }
29838
- sendPromptRequest() {
29839
- const request = new HttpRequest(this.requestData.requestOptions.method, this.requestData.url, this.requestData.requestOptions.body, this.requestData.requestOptions);
29840
- return this.http.request(request);
29841
- }
29842
- processResponse(response) {
29843
- if (this.aiToolDirective.autoClose) {
29844
- this.aiToolDirective.emitOpenClose = true;
29845
- this.aiToolDirective.toggleWindow();
29846
- }
29847
- const responseBody = response.body;
29848
- const responseSuccessEvent = new GridToolbarAIResponseSuccessEvent(response);
29849
- this.aiToolDirective.responseSuccess.emit(responseSuccessEvent);
29850
- if (responseSuccessEvent.isDefaultPrevented()) {
29851
- this.deleteLoadingOutput();
29852
- return;
29853
- }
29854
- const isFilterable = Boolean(this.ctx.grid.filterable);
29855
- const isSortable = Boolean(this.ctx.grid.sortable);
29856
- const isGroupable = Boolean(this.ctx.grid.groupable);
29857
- if (isFilterable && responseBody.filter) {
29858
- this.processFilterResponse(responseBody.filter);
29859
- }
29860
- if (isSortable && responseBody.sort) {
29861
- this.processArrayResponse(responseBody.sort, this.ctx.grid.currentState.sort || [], (item) => item.field, (mergedArray) => this.ctx.grid.sortChange.next(mergedArray));
29862
- }
29863
- if (isGroupable && responseBody.group) {
29864
- this.processArrayResponse(responseBody.group, this.ctx.grid.currentState.group || [], (item) => item.field, (mergedArray) => this.ctx.grid.groupChange.next(mergedArray));
29865
- }
29866
- if (this.ctx.highlightDirective && responseBody.highlight) {
29867
- this.processHighlightResponse(responseBody.highlight);
29868
- }
29869
- const responseContentStart = [`${this.ctx.localization.get('aiAssistantOutputCardBodyContent')} \n`];
29870
- const responseContentBody = responseBody.messages
29871
- .map((output, idx) => `${idx + 1} ${output}`)
29872
- .join('\n');
29873
- const output = {
29874
- id: this.idCounter++,
29875
- title: this.ctx.localization.get('aiAssistantOutputCardTitle'),
29876
- prompt: this.lastMessage,
29877
- output: responseContentStart.concat(responseContentBody).join(''),
29878
- };
29879
- this.deleteLoadingOutput();
29880
- this.aiToolDirective.promptOutputs.unshift(output);
29881
- }
29882
- handleError(error) {
29883
- const responseErrorEvent = new GridToolbarAIResponseErrorEvent(error);
29884
- this.aiToolDirective.responseError.emit(responseErrorEvent);
29885
- if (responseErrorEvent.isDefaultPrevented()) {
29886
- this.deleteLoadingOutput();
29887
- return;
29888
- }
29889
- const output = {
29890
- id: this.idCounter++,
29891
- prompt: this.lastMessage,
29892
- output: error.message
29893
- };
29894
- this.deleteLoadingOutput();
29895
- this.aiToolDirective.promptOutputs.unshift(output);
29896
- }
29897
- deleteLoadingOutput() {
29898
- if (this.aiToolDirective.promptOutputs[0]?.id === this.loadingOutput.id) {
29899
- this.aiToolDirective.promptOutputs.splice(0, 1);
29900
- }
29901
- }
29902
- unsubscribeCurrentRequest() {
29903
- if (this.currentRequestSubscription) {
29904
- this.currentRequestSubscription.unsubscribe();
29905
- this.currentRequestSubscription = null;
29906
- }
29907
- }
29908
- processArrayResponse(newItems, currentItems, getField, updateGrid) {
29909
- if (newItems?.length === 0) {
29910
- updateGrid([]);
29911
- }
29912
- else if (newItems?.length) {
29913
- let mergedArray = [...newItems];
29914
- const newFields = newItems.map(getField);
29915
- const existingItemsToKeep = currentItems.filter(item => !newFields.includes(getField(item)));
29916
- mergedArray = [...mergedArray, ...existingItemsToKeep];
29917
- updateGrid(mergedArray);
29918
- }
29919
- }
29920
- processHighlightResponse(highlight) {
29921
- if (highlight.length === 0) {
29922
- this.ctx.highlightDirective['setState']([]);
29923
- return;
29924
- }
29925
- const highlightedItems = highlightBy(this.ctx.dataBindingDirective['originalData'], highlight, this.columns);
29926
- this.ctx.highlightDirective['setState'](highlightedItems);
29927
- }
29928
- processFilterResponse(filter) {
29929
- const processedFilter = convertDateStringsInFilter(filter);
29930
- const clearFilter = Object.keys(processedFilter).length === 0;
29931
- if (clearFilter) {
29932
- this.ctx.grid.filterChange.next(undefined);
29933
- }
29934
- else if (processedFilter?.filters.length) {
29935
- const currentFilter = this.ctx.grid.currentState.filter;
29936
- let mergedFilter = processedFilter;
29937
- if (currentFilter && currentFilter.filters?.length > 0) {
29938
- mergedFilter = {
29939
- logic: 'and',
29940
- filters: [
29941
- currentFilter,
29942
- processedFilter
29943
- ]
29944
- };
29945
- }
29946
- this.ctx.grid.filterChange.next(mergedFilter);
29947
- }
29948
- }
29949
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AiAssistantComponent, deps: [{ token: i1$8.HttpClient }, { token: ContextService }, { token: ColumnInfoService }], target: i0.ɵɵFactoryTarget.Component });
29950
- 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: `
29951
- <kendo-aiprompt
29952
- #aiPrompt
29953
- [promptSuggestions]="aiPromptSettings?.promptSuggestions"
29954
- [showOutputRating]="aiPromptSettings?.showOutputRating"
29955
- [streaming]="streaming"
29956
- [speechToTextButton]="aiPromptSettings?.speechToTextButton"
29957
- [(activeView)]="activeView"
29958
- [generateButtonSVGIcon]="aiPromptSettings?.generateButtonSVGIcon"
29959
- [generateButtonIcon]="aiPromptSettings?.generateButtonIcon"
29960
- [disabledGenerateButton]="disabledGenerateButton || promptView.textAreaValue?.length === 0"
29961
- [promptOutputs]="aiPromptSettings?.promptOutputs"
29962
- [textAreaSettings]="aiPromptSettings?.textAreaSettings"
29963
- (promptRequest)="onPromptRequest($event)"
29964
- (promptRequestCancel)="cancelRequest()"
29965
- >
29966
- <kendo-aiprompt-prompt-view #promptView></kendo-aiprompt-prompt-view>
29967
- <kendo-aiprompt-output-view></kendo-aiprompt-output-view>
29968
- <ng-template *ngIf="streaming && aiPrompt.streaming" kendoAIPromptOutputTemplate let-output>
29969
- <div class="k-card">
29970
- <div class="k-card-header">
29971
- <div class="k-card-title">
29972
- <span class="k-skeleton k-skeleton-text k-skeleton-pulse" [style.width.px]="200"></span>
29973
- </div>
29974
- <div class="k-card-subtitle">
29975
- <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
29976
- </div>
29977
- </div>
29978
- <div class="k-card-body">
29979
- <span class="k-skeleton k-skeleton-rect k-skeleton-pulse" style="height: 80px;"></span>
29980
- </div>
29981
- <div class="k-card-actions">
29982
- <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
29983
- </div>
29984
- </div>
29985
- </ng-template>
29986
- <ng-template *ngIf="!(streaming && aiPrompt.streaming)" kendoAIPromptOutputBodyTemplate let-output>
29987
- <p>{{output.output}}</p>
29988
- </ng-template>
29989
- <kendo-aiprompt-messages
29990
- [generateOutput]="message('aiAssistantApplyButtonText')"
29991
- ></kendo-aiprompt-messages>
29992
- </kendo-aiprompt>
29993
- `, 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]" }] });
29994
- }
29995
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AiAssistantComponent, decorators: [{
29996
- type: Component,
29997
- args: [{
29998
- standalone: true,
29999
- imports: [NgIf, AIPromptComponent, AIPromptCustomMessagesComponent, PromptViewComponent, OutputViewComponent, AIPromptOutputTemplateDirective, AIPromptOutputBodyTemplateDirective],
30000
- template: `
30001
- <kendo-aiprompt
30002
- #aiPrompt
30003
- [promptSuggestions]="aiPromptSettings?.promptSuggestions"
30004
- [showOutputRating]="aiPromptSettings?.showOutputRating"
30005
- [streaming]="streaming"
30006
- [speechToTextButton]="aiPromptSettings?.speechToTextButton"
30007
- [(activeView)]="activeView"
30008
- [generateButtonSVGIcon]="aiPromptSettings?.generateButtonSVGIcon"
30009
- [generateButtonIcon]="aiPromptSettings?.generateButtonIcon"
30010
- [disabledGenerateButton]="disabledGenerateButton || promptView.textAreaValue?.length === 0"
30011
- [promptOutputs]="aiPromptSettings?.promptOutputs"
30012
- [textAreaSettings]="aiPromptSettings?.textAreaSettings"
30013
- (promptRequest)="onPromptRequest($event)"
30014
- (promptRequestCancel)="cancelRequest()"
30015
- >
30016
- <kendo-aiprompt-prompt-view #promptView></kendo-aiprompt-prompt-view>
30017
- <kendo-aiprompt-output-view></kendo-aiprompt-output-view>
30018
- <ng-template *ngIf="streaming && aiPrompt.streaming" kendoAIPromptOutputTemplate let-output>
30019
- <div class="k-card">
30020
- <div class="k-card-header">
30021
- <div class="k-card-title">
30022
- <span class="k-skeleton k-skeleton-text k-skeleton-pulse" [style.width.px]="200"></span>
30023
- </div>
30024
- <div class="k-card-subtitle">
30025
- <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
30026
- </div>
30027
- </div>
30028
- <div class="k-card-body">
30029
- <span class="k-skeleton k-skeleton-rect k-skeleton-pulse" style="height: 80px;"></span>
30030
- </div>
30031
- <div class="k-card-actions">
30032
- <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
30033
- </div>
30034
- </div>
30035
- </ng-template>
30036
- <ng-template *ngIf="!(streaming && aiPrompt.streaming)" kendoAIPromptOutputBodyTemplate let-output>
30037
- <p>{{output.output}}</p>
30038
- </ng-template>
30039
- <kendo-aiprompt-messages
30040
- [generateOutput]="message('aiAssistantApplyButtonText')"
30041
- ></kendo-aiprompt-messages>
30042
- </kendo-aiprompt>
30043
- `
30044
- }]
30045
- }], ctorParameters: function () { return [{ type: i1$8.HttpClient }, { type: ContextService }, { type: ColumnInfoService }]; }, propDecorators: { aiPrompt: [{
30046
- type: ViewChild,
30047
- args: [AIPromptComponent]
30048
- }] } });
30049
-
30050
- /**
30051
- * Represents an AI Assistant tool of the Grid.
30052
- * Use this directive on any `kendo-toolbar-button` inside a ToolbarComponent in the Grid.
30053
- *
30054
- * @example
30055
- * ```html-no-run
30056
- * <kendo-grid>
30057
- * <kendo-toolbar>
30058
- * <kendo-toolbar-button kendoGridAIAssistantTool></kendo-toolbar-button>
30059
- * </kendo-toolbar>
30060
- * </kendo-grid>
30061
- * ```
30062
- * @remarks
30063
- * Applied to: {@link ToolBarButtonComponent}.
30064
- */
30065
- class AIAssistantToolbarDirective extends ToolbarToolBase {
30066
- windowService;
30067
- host;
30068
- ctx;
30069
- zone;
30070
- refresh;
30071
- /**
30072
- * The URL to which the AI Assistant tool sends the AI request.
30073
- * - 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.
30074
- * - 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.
30075
- */
30076
- requestUrl;
30077
- /**
30078
- * Configures the request options that the AI Assistant tool sends with the AI request.
30079
- *
30080
- * @default { headers: new HttpHeaders({ 'Content-Type': 'application/json' }), role: 'user', method: 'POST', responseType: 'json', withCredentials: false }
30081
- */
30082
- requestOptions;
30083
- /**
30084
- * Configures the initial settings for the AI Assistant Window when opened.
30085
- */
30086
- aiWindowSettings;
30087
- /**
30088
- * Configures the initial settings for the AI Prompt component that the AI Assistant Window component uses when opened.
30089
- */
30090
- aiPromptSettings;
30091
- /**
30092
- * Determines whether to close the AI Assistant Window automatically after a successful request.
30093
- * @default true
30094
- */
30095
- autoClose = true;
30096
- /**
30097
- * Determines whether to keep the AI Prompt's outputs after closing the AI Assistant Window.
30098
- * @default false
30099
- */
30100
- keepOutputHistory = false;
30101
- /**
30102
- * Emits an event before the AI Assistant tool sends the AI request.
30103
- * - When you provide a `requestUrl`, you can handle the event to modify the request options.
30104
- * - When you do not provide a `requestUrl`, you can handle the event to perform an entirely custom request.
30105
- */
30106
- promptRequest = new EventEmitter();
30107
- /**
30108
- * Emits an event when the user clicks the cancel button.
30109
- */
30110
- cancelRequest = new EventEmitter();
30111
- /**
30112
- * Emits an event when the AI Assistant tool completes the AI request successfully.
30113
- * The event contains the response from the AI service and is preventable to allow stopping the default response handling.
30114
- */
30115
- responseSuccess = new EventEmitter();
30116
- /**
30117
- * Emits an event when the AI Assistant tool completes the AI request with an error.
30118
- * The event contains the error response from the AI service and is preventable to allow stopping the default error handling.
30119
- */
30120
- responseError = new EventEmitter();
30121
- /**
30122
- * Emits an event when the AI Assistant tool closes.
30123
- */
30124
- close = new EventEmitter();
30125
- /**
30126
- * Emits an event when the AI Assistant tool opens.
30127
- */
30128
- open = new EventEmitter();
30129
- tableWizardIcon = tableWizardIcon;
30130
- emitOpenClose = false;
30131
- promptOutputs = [];
30132
- windowRef;
30133
- subs = new Subscription();
30134
- defaultAiPromptSettings = {
30135
- speechToTextButton: true,
30136
- generateButtonSVGIcon: this.tableWizardIcon,
30137
- generateButtonIcon: 'table-wizard'
30138
- };
30139
- constructor(windowService, host, ctx, zone, refresh, cdr) {
30140
- super(host, ToolbarToolName.aiAssistant, ctx, zone, cdr);
30141
- this.windowService = windowService;
30142
- this.host = host;
30143
- this.ctx = ctx;
30144
- this.zone = zone;
30145
- this.refresh = refresh;
30146
- this.host.rounded = 'full';
30147
- this.host.themeColor = 'primary';
30148
- this.host.showText = 'never';
30149
- }
30150
- ngOnInit() {
30151
- this.subs.add(this.host.click.subscribe(() => this.onClick()));
30152
- const hasToolbarIcon = isPresent$1(this.host.toolbarOptions.icon) && this.host.toolbarOptions.icon !== '';
30153
- const hasOverflowIcon = isPresent$1(this.host.overflowOptions.icon) && this.host.overflowOptions.icon !== '';
30154
- const hasIcon = hasToolbarIcon && hasOverflowIcon;
30155
- const hasSvgIcon = isPresent$1(this.host.toolbarOptions.svgIcon) && isPresent$1(this.host.overflowOptions.svgIcon);
30156
- if (!hasIcon) {
30157
- this.host.icon = 'sparkles';
30158
- }
30159
- if (!hasSvgIcon) {
30160
- this.host.svgIcon = sparklesIcon;
30161
- }
30162
- this.requestOptions = { ...DEFAULT_AI_REQUEST_OPTIONS, ...this.requestOptions };
30163
- }
30164
- ngAfterViewInit() {
30165
- super.ngAfterViewInit();
30166
- this.zone.onStable.pipe(take(1)).subscribe(() => {
30167
- this.buttonElement?.setAttribute('aria-haspopup', 'dialog');
30168
- this.buttonElement?.setAttribute('aria-expanded', 'false');
30169
- const needsTitle = this.host.showText !== 'always' && this.host.showText !== 'toolbar';
30170
- if (needsTitle && !this.host.title) {
30171
- this.buttonElement?.setAttribute('title', this.ctx.localization.get('aiAssistantToolbarToolText'));
30172
- }
30173
- });
30174
- this.subs.add(this.refresh.onRefresh.pipe(filter((tool) => tool === this.host)).subscribe((tool) => {
30175
- if (tool.overflows && this.windowRef) {
30176
- this.windowRef.close();
30177
- }
30178
- }));
30179
- }
30180
- ngOnDestroy() {
30181
- super.ngOnDestroy();
30182
- this.subs.unsubscribe();
30183
- this.promptOutputs = [];
30184
- }
30185
- /**
30186
- * @hidden
30187
- */
30188
- onClick() {
30189
- this.emitOpenClose = true;
30190
- this.toggleWindow();
30191
- }
30192
- /**
30193
- * Toggles the AI Assistant window.
30194
- */
30195
- toggleWindow() {
30196
- if (!this.windowRef) {
30197
- this.openWindow();
30198
- }
30199
- else {
30200
- this.closeWindow();
30201
- }
30202
- }
30203
- openWindow() {
30204
- if (!this.keepOutputHistory) {
30205
- this.promptOutputs = [];
30206
- }
30207
- const defaultWindowWidth = 437;
30208
- const rtl = this.ctx.localization.rtl;
30209
- const defaultWindowSettings = {
30210
- left: rtl ? this.buttonElement.offsetLeft - (this.aiWindowSettings.width || defaultWindowWidth) : this.buttonElement.offsetLeft + this.buttonElement.offsetWidth,
30211
- top: this.buttonElement.offsetTop + this.buttonElement.offsetHeight,
30212
- width: defaultWindowWidth,
30213
- title: this.ctx.localization.get('aiAssistantWindowTitle'),
30214
- cssClass: 'k-grid-assistant-window',
30215
- content: AiAssistantComponent,
30216
- autoFocusedElement: '.k-input-inner',
30217
- appendTo: this.ctx.grid.windowContainer
30218
- };
30219
- this.aiWindowSettings = {
30220
- ...defaultWindowSettings,
30221
- ...this.aiWindowSettings
30222
- };
30223
- this.windowRef = this.windowService.open(this.aiWindowSettings);
30224
- this.windowRef.window.instance.messages = {
30225
- closeTitle: this.ctx.localization.get('aiAssistantWindowCloseTitle'),
30226
- maximizeTitle: this.ctx.localization.get('aiAssistantWindowMaximizeTitle'),
30227
- minimizeTitle: this.ctx.localization.get('aiAssistantWindowMinimizeTitle'),
30228
- restoreTitle: this.ctx.localization.get('aiAssistantWindowRestoreTitle')
30229
- };
30230
- const aiPrompt = this.windowRef.content.instance;
30231
- aiPrompt.requestUrl = this.requestUrl;
30232
- aiPrompt.requestOptions = this.requestOptions;
30233
- aiPrompt.aiToolDirective = this;
30234
- aiPrompt.disabledGenerateButton = this.aiPromptSettings?.disabledGenerateButton;
30235
- aiPrompt.streaming = this.aiPromptSettings?.streaming || false;
30236
- aiPrompt.activeView = this.aiPromptSettings?.activeView || 0;
30237
- aiPrompt.aiPromptSettings = { ...this.defaultAiPromptSettings, ...this.aiPromptSettings };
30238
- if (!aiPrompt.aiPromptSettings.promptOutputs) {
30239
- aiPrompt.aiPromptSettings.promptOutputs = this.promptOutputs;
30240
- }
30241
- if (this.emitOpenClose) {
30242
- this.zone.onStable.pipe(take(1)).subscribe(() => {
30243
- const event = {
30244
- aiWindow: this.windowRef.window.instance,
30245
- aiPrompt: this.windowRef.content.instance.aiPrompt
30246
- };
30247
- this.open.emit(event);
30248
- this.emitOpenClose = false;
30249
- });
30250
- }
30251
- this.subs.add(this.windowRef.window.instance.close.subscribe(() => {
30252
- this.emitOpenClose = true;
30253
- this.closeWindow(true);
30254
- }));
30255
- this.host.selected = true;
30256
- }
30257
- closeWindow(focusAnchor = false) {
30258
- this.windowRef.close();
30259
- if (this.emitOpenClose) {
30260
- this.close.emit();
30261
- this.emitOpenClose = false;
30262
- }
30263
- this.windowRef = null;
30264
- this.buttonElement?.setAttribute('aria-expanded', 'false');
30265
- this.buttonElement?.removeAttribute('aria-controls');
30266
- this.host.selected = false;
30267
- focusAnchor && this.buttonElement?.focus();
30268
- }
30269
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIAssistantToolbarDirective, deps: [{ token: i1$7.WindowService }, { token: i54.ToolBarButtonComponent }, { token: ContextService }, { token: i0.NgZone }, { token: i54.RefreshService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
30270
- 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 });
30271
- }
30272
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIAssistantToolbarDirective, decorators: [{
30273
- type: Directive,
30274
- args: [{
30275
- selector: '[kendoGridAIAssistantTool]',
30276
- standalone: true
30277
- }]
30278
- }], ctorParameters: function () { return [{ type: i1$7.WindowService }, { type: i54.ToolBarButtonComponent }, { type: ContextService }, { type: i0.NgZone }, { type: i54.RefreshService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { requestUrl: [{
30279
- type: Input
30280
- }], requestOptions: [{
30281
- type: Input
30282
- }], aiWindowSettings: [{
30283
- type: Input
30284
- }], aiPromptSettings: [{
30285
- type: Input
30286
- }], autoClose: [{
30287
- type: Input
30288
- }], keepOutputHistory: [{
30289
- type: Input
30290
- }], promptRequest: [{
30291
- type: Output
30292
- }], cancelRequest: [{
30293
- type: Output
30294
- }], responseSuccess: [{
30295
- type: Output
30296
- }], responseError: [{
30297
- type: Output
30298
- }], close: [{
30299
- type: Output
30300
- }], open: [{
30301
- type: Output
30302
- }] } });
30303
-
30304
29626
  const createControl = (source) => (acc, key) => {
30305
29627
  acc[key] = new FormControl(source[key]);
30306
29628
  return acc;
@@ -31095,7 +30417,6 @@ class GridComponent {
31095
30417
  this._customToolbarTemplate = customToolbarTemplate;
31096
30418
  }
31097
30419
  columnMenuTemplates;
31098
- aiAssistantToolbarTool;
31099
30420
  lockedHeader;
31100
30421
  header;
31101
30422
  footer = new QueryList();
@@ -32665,7 +31986,7 @@ class GridComponent {
32665
31986
  ColumnMenuService,
32666
31987
  MenuTabbingService,
32667
31988
  DataMappingService
32668
- ], queries: [{ propertyName: "aiAssistantToolbarTool", first: true, predicate: AIAssistantToolbarDirective, descendants: true }, { propertyName: "columns", predicate: ColumnBase }, { propertyName: "detailTemplateChildren", predicate: DetailTemplateDirective }, { propertyName: "cellLoadingTemplateChildren", predicate: CellLoadingTemplateDirective }, { propertyName: "loadingTemplateChildren", predicate: LoadingTemplateDirective }, { propertyName: "statusBarTemplateChildren", predicate: StatusBarTemplateDirective }, { propertyName: "noRecordsTemplateChildren", predicate: NoRecordsTemplateDirective }, { propertyName: "pagerTemplateChildren", predicate: PagerTemplateDirective }, { propertyName: "toolbarTemplateChildren", predicate: ToolbarTemplateDirective }, { propertyName: "columnMenuTemplates", predicate: ColumnMenuTemplateDirective }], viewQueries: [{ propertyName: "lockedHeader", first: true, predicate: ["lockedHeader"], descendants: true }, { propertyName: "header", first: true, predicate: ["header"], descendants: true }, { propertyName: "ariaRoot", first: true, predicate: ["ariaRoot"], descendants: true, static: true }, { propertyName: "dragTargetContainer", first: true, predicate: DragTargetContainerDirective, descendants: true }, { propertyName: "dropTargetContainer", first: true, predicate: DropTargetContainerDirective, descendants: true }, { propertyName: "dialogContainer", first: true, predicate: ["dialogContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "windowContainer", first: true, predicate: ["windowContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "adaptiveRenderer", first: true, predicate: AdaptiveRendererComponent, descendants: true }, { propertyName: "listComponent", first: true, predicate: ListComponent, descendants: true }, { propertyName: "footer", predicate: ["footer"], descendants: true }], exportAs: ["kendoGrid"], usesOnChanges: true, ngImport: i0, template: `
31989
+ ], queries: [{ propertyName: "columns", predicate: ColumnBase }, { propertyName: "detailTemplateChildren", predicate: DetailTemplateDirective }, { propertyName: "cellLoadingTemplateChildren", predicate: CellLoadingTemplateDirective }, { propertyName: "loadingTemplateChildren", predicate: LoadingTemplateDirective }, { propertyName: "statusBarTemplateChildren", predicate: StatusBarTemplateDirective }, { propertyName: "noRecordsTemplateChildren", predicate: NoRecordsTemplateDirective }, { propertyName: "pagerTemplateChildren", predicate: PagerTemplateDirective }, { propertyName: "toolbarTemplateChildren", predicate: ToolbarTemplateDirective }, { propertyName: "columnMenuTemplates", predicate: ColumnMenuTemplateDirective }], viewQueries: [{ propertyName: "lockedHeader", first: true, predicate: ["lockedHeader"], descendants: true }, { propertyName: "header", first: true, predicate: ["header"], descendants: true }, { propertyName: "ariaRoot", first: true, predicate: ["ariaRoot"], descendants: true, static: true }, { propertyName: "dragTargetContainer", first: true, predicate: DragTargetContainerDirective, descendants: true }, { propertyName: "dropTargetContainer", first: true, predicate: DropTargetContainerDirective, descendants: true }, { propertyName: "dialogContainer", first: true, predicate: ["dialogContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "windowContainer", first: true, predicate: ["windowContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "adaptiveRenderer", first: true, predicate: AdaptiveRendererComponent, descendants: true }, { propertyName: "listComponent", first: true, predicate: ListComponent, descendants: true }, { propertyName: "footer", predicate: ["footer"], descendants: true }], exportAs: ["kendoGrid"], usesOnChanges: true, ngImport: i0, template: `
32669
31990
  <ng-container kendoGridLocalizedMessages
32670
31991
  i18n-groupPanelEmpty="kendo.grid.groupPanelEmpty|The label visible in the Grid group panel when it is empty"
32671
31992
  groupPanelEmpty="Drag a column header and drop it here to group by that column"
@@ -33468,10 +32789,10 @@ class GridComponent {
33468
32789
  </kendo-pager-info>
33469
32790
  </ng-template>
33470
32791
  <div #dialogContainer></div>
32792
+ <div #windowContainer></div>
33471
32793
 
33472
32794
  <kendo-grid-adaptive-renderer *ngIf="isAdaptiveModeEnabled"></kendo-grid-adaptive-renderer>
33473
32795
  <kendo-resize-sensor *ngIf="isVirtual" (resize)="onResize()"></kendo-resize-sensor>
33474
- <div *ngIf="aiAssistantToolbarTool" #windowContainer></div>
33475
32796
 
33476
32797
  <div kendoWatermarkOverlay *ngIf="showLicenseWatermark" [licenseMessage]="licenseMessage"></div>
33477
32798
  `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoGridLocalizedMessages]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ToolbarComponent, selector: "kendo-grid-toolbar", inputs: ["position", "size", "navigable"] }, { kind: "component", type: GroupPanelComponent, selector: "kendo-grid-group-panel", inputs: ["text", "navigable", "groups"], outputs: ["change"] }, { kind: "directive", type: TableDirective, selector: "[kendoGridResizableTable]", inputs: ["locked", "virtualColumns"] }, { kind: "directive", type: GridTableDirective, selector: "[kendoGridTable]", inputs: ["size"] }, { kind: "component", type: ColGroupComponent, selector: "[kendoGridColGroup]", inputs: ["columns", "groups", "detailTemplate", "sort"] }, { kind: "component", type: HeaderComponent, selector: "[kendoGridHeader]", inputs: ["totalColumnLevels", "columns", "groups", "detailTemplate", "scrollable", "filterable", "sort", "filter", "sortable", "groupable", "lockedColumnsCount", "resizable", "reorderable", "columnMenu", "columnMenuTemplate", "totalColumnsCount", "totalColumns", "tabIndex", "size"] }, { kind: "directive", type: ResizableContainerDirective, selector: "[kendoGridResizableContainer]", inputs: ["lockedWidth", "kendoGridResizableContainer"] }, { kind: "component", type: ListComponent, selector: "kendo-grid-list", inputs: ["data", "groups", "total", "rowHeight", "detailRowHeight", "take", "skip", "columns", "detailTemplate", "noRecordsTemplate", "selectable", "groupable", "filterable", "rowClass", "rowSticky", "loading", "trackBy", "virtualColumns", "isVirtual", "cellLoadingTemplate", "loadingTemplate", "sort", "size"], outputs: ["contentScroll", "pageChange", "scrollBottom"] }, { kind: "directive", type: DragTargetContainerDirective, selector: "[kendoDragTargetContainer]", inputs: ["hint", "dragTargetFilter", "dragHandle", "dragDelay", "threshold", "dragTargetId", "dragData", "dragDisabled", "mode", "cursorStyle", "hintContext"], outputs: ["onDragReady", "onPress", "onDragStart", "onDrag", "onRelease", "onDragEnd"], exportAs: ["kendoDragTargetContainer"] }, { kind: "directive", type: DropTargetContainerDirective, selector: "[kendoDropTargetContainer]", inputs: ["dropTargetFilter", "dropDisabled"], outputs: ["onDragEnter", "onDragOver", "onDragLeave", "onDrop"], exportAs: ["kendoDropTargetContainer"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["enableDrag"], outputs: ["kendoPress", "kendoDrag", "kendoRelease"] }, { kind: "directive", type: GridMarqueeDirective, selector: "[kendoGridSelectionMarquee]" }, { kind: "component", type: FooterComponent, selector: "[kendoGridFooter]", inputs: ["columns", "groups", "detailTemplate", "scrollable", "lockedColumnsCount", "logicalRowIndex", "totalColumns", "totalColumnsCount"] }, { kind: "component", type: TableBodyComponent, selector: "[kendoGridTableBody]", inputs: ["columns", "allColumns", "groups", "detailTemplate", "noRecordsTemplate", "rowsToRender", "skip", "selectable", "filterable", "noRecordsText", "isLocked", "isLoading", "isVirtual", "cellLoadingTemplate", "skipGroupDecoration", "lockedColumnsCount", "totalColumnsCount", "virtualColumns", "trackBy", "rowSticky", "totalColumns", "rowClass", "rowHeight", "detailRowHeight"] }, { kind: "component", type: LoadingComponent, selector: "[kendoGridLoading]", inputs: ["loadingTemplate"] }, { kind: "component", type: StatusBarComponent, selector: "kendo-grid-status-bar", inputs: ["statusBarTemplate"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: WatermarkOverlayComponent, selector: "div[kendoWatermarkOverlay]", inputs: ["licenseMessage"] }, { kind: "component", type: i53.CustomMessagesComponent, selector: "kendo-datapager-messages, kendo-pager-messages" }, { kind: "component", type: i53.PagerInfoComponent, selector: "kendo-datapager-info, kendo-pager-info" }, { kind: "component", type: i53.PagerInputComponent, selector: "kendo-datapager-input, kendo-pager-input", inputs: ["showPageText", "size"] }, { kind: "component", type: i53.PagerNextButtonsComponent, selector: "kendo-datapager-next-buttons, kendo-pager-next-buttons", inputs: ["size"] }, { kind: "component", type: i53.PagerNumericButtonsComponent, selector: "kendo-datapager-numeric-buttons, kendo-pager-numeric-buttons", inputs: ["buttonCount", "size"] }, { kind: "component", type: i53.PagerPageSizesComponent, selector: "kendo-datapager-page-sizes, kendo-pager-page-sizes", inputs: ["showItemsText", "pageSizes", "size", "adaptiveMode"] }, { kind: "component", type: i53.PagerPrevButtonsComponent, selector: "kendo-datapager-prev-buttons, kendo-pager-prev-buttons", inputs: ["size"] }, { kind: "directive", type: i53.PagerTemplateDirective, selector: "[kendoDataPagerTemplate], [kendoPagerTemplate]" }, { kind: "component", type: i53.PagerComponent, selector: "kendo-datapager, kendo-pager", inputs: ["externalTemplate", "total", "skip", "pageSize", "buttonCount", "info", "type", "pageSizeValues", "previousNext", "navigable", "size", "responsive", "adaptiveMode"], outputs: ["pageChange", "pageSizeChange", "pagerInputVisibilityChange", "pageTextVisibilityChange", "itemsTextVisibilityChange"], exportAs: ["kendoDataPager", "kendoPager"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AdaptiveRendererComponent, selector: "kendo-grid-adaptive-renderer" }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }], encapsulation: i0.ViewEncapsulation.None });
@@ -34337,10 +33658,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
34337
33658
  </kendo-pager-info>
34338
33659
  </ng-template>
34339
33660
  <div #dialogContainer></div>
33661
+ <div #windowContainer></div>
34340
33662
 
34341
33663
  <kendo-grid-adaptive-renderer *ngIf="isAdaptiveModeEnabled"></kendo-grid-adaptive-renderer>
34342
33664
  <kendo-resize-sensor *ngIf="isVirtual" (resize)="onResize()"></kendo-resize-sensor>
34343
- <div *ngIf="aiAssistantToolbarTool" #windowContainer></div>
34344
33665
 
34345
33666
  <div kendoWatermarkOverlay *ngIf="showLicenseWatermark" [licenseMessage]="licenseMessage"></div>
34346
33667
  `,
@@ -34549,9 +33870,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
34549
33870
  }], columnMenuTemplates: [{
34550
33871
  type: ContentChildren,
34551
33872
  args: [ColumnMenuTemplateDirective]
34552
- }], aiAssistantToolbarTool: [{
34553
- type: ContentChild,
34554
- args: [AIAssistantToolbarDirective]
34555
33873
  }], lockedHeader: [{
34556
33874
  type: ViewChild,
34557
33875
  args: ['lockedHeader']
@@ -37436,518 +36754,1196 @@ class FilterCommandToolbarDirective {
37436
36754
  get buttonElement() {
37437
36755
  return this.host.getButton();
37438
36756
  }
37439
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterCommandToolbarDirective, deps: [{ token: i54.ToolBarButtonComponent }, { token: i2.PopupService }, { token: ContextService }, { token: FilterService }, { token: ColumnInfoService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: AdaptiveGridService }], target: i0.ɵɵFactoryTarget.Directive });
37440
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FilterCommandToolbarDirective, isStandalone: true, selector: "[kendoGridFilterTool]", ngImport: i0 });
36757
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterCommandToolbarDirective, deps: [{ token: i54.ToolBarButtonComponent }, { token: i2.PopupService }, { token: ContextService }, { token: FilterService }, { token: ColumnInfoService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: AdaptiveGridService }], target: i0.ɵɵFactoryTarget.Directive });
36758
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FilterCommandToolbarDirective, isStandalone: true, selector: "[kendoGridFilterTool]", ngImport: i0 });
36759
+ }
36760
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterCommandToolbarDirective, decorators: [{
36761
+ type: Directive,
36762
+ args: [{
36763
+ selector: '[kendoGridFilterTool]',
36764
+ standalone: true
36765
+ }]
36766
+ }], ctorParameters: function () { return [{ type: i54.ToolBarButtonComponent }, { type: i2.PopupService }, { type: ContextService }, { type: FilterService }, { type: ColumnInfoService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: AdaptiveGridService }]; } });
36767
+
36768
+ /**
36769
+ * Represents the `edit` command in the Grid. Apply this directive to any `kendo-toolbar-button`
36770
+ * element inside a ToolbarComponent used in the Grid.
36771
+ *
36772
+ * When you click the toolbar button with this directive, the
36773
+ * [`edit`]({% slug api_grid_gridcomponent %}#toc-edit) event fires.
36774
+ *
36775
+ * @example
36776
+ * ```html
36777
+ * <kendo-grid>
36778
+ * <kendo-toolbar>
36779
+ * <kendo-toolbar-button text="Edit" kendoGridEditTool></kendo-toolbar-button>
36780
+ * </kendo-toolbar>
36781
+ * </kendo-grid>
36782
+ * ```
36783
+ * @remarks
36784
+ * Applied to: {@link ToolBarButtonComponent}.
36785
+ */
36786
+ class EditCommandToolbarDirective extends ToolbarEditingToolBase {
36787
+ editService;
36788
+ constructor(editService, host, selection, ctx, zone, cdr) {
36789
+ super(host, ToolbarToolName.edit, ctx, zone, cdr, editService, selection);
36790
+ this.editService = editService;
36791
+ }
36792
+ /**
36793
+ * @hidden
36794
+ */
36795
+ onClick(e) {
36796
+ e.preventDefault();
36797
+ if (!this.isSelectionPresent) {
36798
+ return;
36799
+ }
36800
+ this.editService.beginEdit(this.lastSelectionIndex);
36801
+ }
36802
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EditCommandToolbarDirective, deps: [{ token: EditService }, { token: i54.ToolBarButtonComponent }, { token: SelectionService }, { token: ContextService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
36803
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: EditCommandToolbarDirective, isStandalone: true, selector: "[kendoGridEditTool]", usesInheritance: true, ngImport: i0 });
36804
+ }
36805
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EditCommandToolbarDirective, decorators: [{
36806
+ type: Directive,
36807
+ args: [{
36808
+ selector: '[kendoGridEditTool]',
36809
+ standalone: true
36810
+ }]
36811
+ }], ctorParameters: function () { return [{ type: EditService }, { type: i54.ToolBarButtonComponent }, { type: SelectionService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; } });
36812
+
36813
+ /**
36814
+ * Represents the `save` command in the Grid. Apply this directive to any `kendo-toolbar-button`
36815
+ * element inside a ToolbarComponent used in the Grid.
36816
+ *
36817
+ * When you click the toolbar button with this directive, the
36818
+ * [`save`]({% slug api_grid_gridcomponent %}#toc-save) event fires.
36819
+ *
36820
+ * @example
36821
+ * ```html
36822
+ * <kendo-grid>
36823
+ * <kendo-toolbar>
36824
+ * <kendo-toolbar-button text="Save" kendoGridSaveTool></kendo-toolbar-button>
36825
+ * </kendo-toolbar>
36826
+ * </kendo-grid>
36827
+ * ```
36828
+ * @remarks
36829
+ * Applied to: {@link ToolBarButtonComponent}.
36830
+ */
36831
+ class SaveCommandToolbarDirective extends ToolbarEditingToolBase {
36832
+ editService;
36833
+ constructor(editService, host, selection, ctx, zone, cdr) {
36834
+ super(host, ToolbarToolName.save, ctx, zone, cdr, editService, selection);
36835
+ this.editService = editService;
36836
+ }
36837
+ /**
36838
+ * @hidden
36839
+ */
36840
+ onClick(e) {
36841
+ e.preventDefault();
36842
+ if (this.editService.hasNewItem) {
36843
+ this.editService.save();
36844
+ }
36845
+ else if (this.isSelectionPresent && this.editService.isEdited(this.lastSelectionIndex)) {
36846
+ this.editService.save(this.lastSelectionIndex);
36847
+ }
36848
+ else {
36849
+ this.editService.editedIndices.forEach(i => this.editService.save(i.index));
36850
+ }
36851
+ }
36852
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SaveCommandToolbarDirective, deps: [{ token: EditService }, { token: i54.ToolBarButtonComponent }, { token: SelectionService }, { token: ContextService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
36853
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: SaveCommandToolbarDirective, isStandalone: true, selector: "[kendoGridSaveTool]", usesInheritance: true, ngImport: i0 });
36854
+ }
36855
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SaveCommandToolbarDirective, decorators: [{
36856
+ type: Directive,
36857
+ args: [{
36858
+ selector: '[kendoGridSaveTool]',
36859
+ standalone: true
36860
+ }]
36861
+ }], ctorParameters: function () { return [{ type: EditService }, { type: i54.ToolBarButtonComponent }, { type: SelectionService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; } });
36862
+
36863
+ /**
36864
+ * Represents the `remove` command in the Grid. Apply this directive to any `kendo-toolbar-button`
36865
+ * element inside a ToolbarComponent used in the Grid.
36866
+ *
36867
+ * When you click the toolbar button with this directive, the
36868
+ * [`remove`]({% slug api_grid_gridcomponent %}#toc-remove) event fires.
36869
+ *
36870
+ * @example
36871
+ * ```html
36872
+ * <kendo-grid>
36873
+ * <kendo-toolbar>
36874
+ * <kendo-toolbar-button text="Remove row" kendoGridRemoveTool></kendo-toolbar-button>
36875
+ * </kendo-toolbar>
36876
+ * </kendo-grid>
36877
+ * ```
36878
+ * @remarks
36879
+ * Applied to: {@link ToolBarButtonComponent}.
36880
+ */
36881
+ class RemoveCommandToolbarDirective extends ToolbarEditingToolBase {
36882
+ editService;
36883
+ selection;
36884
+ constructor(editService, host, selection, ctx, zone, cdr) {
36885
+ super(host, ToolbarToolName.remove, ctx, zone, cdr, editService, selection);
36886
+ this.editService = editService;
36887
+ this.selection = selection;
36888
+ }
36889
+ /**
36890
+ * @hidden
36891
+ */
36892
+ onClick(e) {
36893
+ e.preventDefault();
36894
+ if (this.isSelectionPresent) {
36895
+ this.editService.remove(this.lastSelectionIndex);
36896
+ }
36897
+ }
36898
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RemoveCommandToolbarDirective, deps: [{ token: EditService }, { token: i54.ToolBarButtonComponent }, { token: SelectionService }, { token: ContextService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
36899
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: RemoveCommandToolbarDirective, isStandalone: true, selector: "[kendoGridRemoveTool]", usesInheritance: true, ngImport: i0 });
36900
+ }
36901
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RemoveCommandToolbarDirective, decorators: [{
36902
+ type: Directive,
36903
+ args: [{
36904
+ selector: '[kendoGridRemoveTool]',
36905
+ standalone: true
36906
+ }]
36907
+ }], ctorParameters: function () { return [{ type: EditService }, { type: i54.ToolBarButtonComponent }, { type: SelectionService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; } });
36908
+
36909
+ /**
36910
+ * Represents the `cancel` command in the Grid.
36911
+ * Apply this directive to any `kendo-toolbar-button` element inside a ToolbarComponent in the Grid.
36912
+ *
36913
+ * When you click the toolbar button with this directive, the [`cancel`]({% slug api_grid_gridcomponent %}#toc-cancel) event triggers.
36914
+ *
36915
+ * @example
36916
+ * ```html
36917
+ * <kendo-grid>
36918
+ * <kendo-toolbar>
36919
+ * <kendo-toolbar-button text="Cancel" kendoGridCancelTool></kendo-toolbar-button>
36920
+ * </kendo-toolbar>
36921
+ * </kendo-grid>
36922
+ * ```
36923
+ * @remarks
36924
+ * Applied to: {@link ToolBarButtonComponent}.
36925
+ */
36926
+ class CancelCommandToolbarDirective extends ToolbarEditingToolBase {
36927
+ editService;
36928
+ constructor(editService, host, selection, ctx, zone, cdr) {
36929
+ super(host, ToolbarToolName.cancel, ctx, zone, cdr, editService, selection);
36930
+ this.editService = editService;
36931
+ }
36932
+ /**
36933
+ * @hidden
36934
+ */
36935
+ onClick(e) {
36936
+ e.preventDefault();
36937
+ if (this.editService.hasNewItem) {
36938
+ this.editService.endEdit();
36939
+ }
36940
+ else if (this.isSelectionPresent && this.editService.isEdited(this.lastSelectionIndex)) {
36941
+ this.editService.endEdit(this.lastSelectionIndex);
36942
+ }
36943
+ else {
36944
+ this.editService.editedIndices.forEach(i => this.editService.endEdit(i.index));
36945
+ }
36946
+ }
36947
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CancelCommandToolbarDirective, deps: [{ token: EditService }, { token: i54.ToolBarButtonComponent }, { token: SelectionService }, { token: ContextService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
36948
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CancelCommandToolbarDirective, isStandalone: true, selector: "[kendoGridCancelTool]", usesInheritance: true, ngImport: i0 });
36949
+ }
36950
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CancelCommandToolbarDirective, decorators: [{
36951
+ type: Directive,
36952
+ args: [{
36953
+ selector: '[kendoGridCancelTool]',
36954
+ standalone: true
36955
+ }]
36956
+ }], ctorParameters: function () { return [{ type: EditService }, { type: i54.ToolBarButtonComponent }, { type: SelectionService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; } });
36957
+
36958
+ let incrementingId = 0;
36959
+ /**
36960
+ * Represents the toolbar tool for grouping columns of the Grid.
36961
+ * Use this directive on any `kendo-toolbar-button` inside a ToolbarComponent in the Grid.
36962
+ * When you click the toolbar button with this directive, the `group` event is triggered.
36963
+ *
36964
+ * @example
36965
+ * ```html
36966
+ * <kendo-grid>
36967
+ * <kendo-toolbar>
36968
+ * <kendo-toolbar-button text="Group" kendoGridGroupTool></kendo-toolbar-button>
36969
+ * </kendo-toolbar>
36970
+ * </kendo-grid>
36971
+ * ```
36972
+ * @remarks
36973
+ * Applied to: {@link ToolBarButtonComponent}.
36974
+ */
36975
+ class GroupCommandToolbarDirective {
36976
+ host;
36977
+ popupService;
36978
+ ctx;
36979
+ ngZone;
36980
+ renderer;
36981
+ adaptiveGridService;
36982
+ popupRef;
36983
+ nextId = incrementingId++;
36984
+ toolSubs = new Subscription();
36985
+ popupSubs;
36986
+ actionSheetCloseSub;
36987
+ removeClickListener;
36988
+ constructor(host, popupService, ctx, ngZone, renderer, adaptiveGridService) {
36989
+ this.host = host;
36990
+ this.popupService = popupService;
36991
+ this.ctx = ctx;
36992
+ this.ngZone = ngZone;
36993
+ this.renderer = renderer;
36994
+ this.adaptiveGridService = adaptiveGridService;
36995
+ }
36996
+ ngOnInit() {
36997
+ this.toolSubs = this.host.click.subscribe(e => this.onClick(e));
36998
+ this.toolSubs.add(this.ctx.grid.groupChange.subscribe(group => {
36999
+ this.host.showBadge = this.isGroupingApplied(group);
37000
+ }));
37001
+ this.host.hasBadgeContainer = true;
37002
+ this.host.showBadge = this.isGroupingApplied(this.ctx.grid.group);
37003
+ const hasToolbarIcon = isPresent$1(this.host.toolbarOptions.icon) && this.host.toolbarOptions.icon !== '';
37004
+ const hasOverflowIcon = isPresent$1(this.host.overflowOptions.icon) && this.host.overflowOptions.icon !== '';
37005
+ const hasIcon = hasToolbarIcon && hasOverflowIcon;
37006
+ const hasSvgIcon = isPresent$1(this.host.toolbarOptions.svgIcon) && isPresent$1(this.host.overflowOptions.svgIcon);
37007
+ if (!hasIcon) {
37008
+ this.host.icon = 'group';
37009
+ }
37010
+ if (!hasSvgIcon) {
37011
+ this.host.svgIcon = groupIcon;
37012
+ }
37013
+ }
37014
+ ngAfterViewInit() {
37015
+ if (!isPresent$1(this.host.text)) {
37016
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => {
37017
+ this.host.text = this.ctx.localization.get(`groupToolbarToolText`);
37018
+ });
37019
+ }
37020
+ this.buttonElement?.setAttribute('aria-haspopup', 'dialog');
37021
+ this.buttonElement?.setAttribute('aria-expanded', 'false');
37022
+ this.buttonElement?.setAttribute('title', this.ctx.localization.get('groupToolbarToolText'));
37023
+ }
37024
+ ngOnDestroy() {
37025
+ if (this.toolSubs) {
37026
+ this.toolSubs.unsubscribe();
37027
+ }
37028
+ if (this.popupSubs) {
37029
+ this.popupSubs.unsubscribe();
37030
+ }
37031
+ if (this.popupRef) {
37032
+ this.popupRef.close();
37033
+ this.popupRef = null;
37034
+ }
37035
+ if (this.actionSheetCloseSub) {
37036
+ this.actionSheetCloseSub.unsubscribe();
37037
+ this.actionSheetCloseSub = null;
37038
+ }
37039
+ if (this.removeClickListener) {
37040
+ this.removeClickListener();
37041
+ this.removeClickListener = null;
37042
+ }
37043
+ }
37044
+ onClick(e) {
37045
+ e.preventDefault();
37046
+ if (this.ctx.grid.adaptiveMode === 'auto' && this.adaptiveGridService.windowSize !== 'large') {
37047
+ if (!this.ctx.grid.isActionSheetExpanded) {
37048
+ this.adaptiveGridService.viewType = 'groupToolbarTool';
37049
+ this.ctx.grid.adaptiveRenderer.actionSheet.toggle(true);
37050
+ this.host.selected = true;
37051
+ this.actionSheetCloseSub = this.ctx.grid.adaptiveRenderer.actionSheet.collapse.subscribe(() => this.host.selected = false);
37052
+ }
37053
+ }
37054
+ else {
37055
+ if (this.popupRef) {
37056
+ this.closePopup();
37057
+ return;
37058
+ }
37059
+ this.openPopup();
37060
+ }
37061
+ }
37062
+ openPopup() {
37063
+ const direction = this.ctx.localization.rtl ? 'right' : 'left';
37064
+ this.popupRef = this.popupService.open({
37065
+ anchor: this.buttonElement,
37066
+ content: GroupToolbarToolComponent,
37067
+ popupClass: 'k-grid-columnmenu-popup',
37068
+ positionMode: 'absolute',
37069
+ anchorAlign: { vertical: 'bottom', horizontal: direction },
37070
+ popupAlign: { vertical: 'top', horizontal: direction }
37071
+ });
37072
+ this.adaptiveGridService.popupRef = this.popupRef;
37073
+ this.setPopupAttributes();
37074
+ this.host.selected = true;
37075
+ this.ngZone.runOutsideAngular(() => {
37076
+ if (!isDocumentAvailable()) {
37077
+ return;
37078
+ }
37079
+ this.removeClickListener = this.renderer.listen('document', 'click', (e) => {
37080
+ if (this.popupRef && !closest$1(e.target, node => node === this.popupRef.popupElement || node === this.buttonElement)) {
37081
+ this.ngZone.run(() => {
37082
+ this.closePopup();
37083
+ });
37084
+ }
37085
+ });
37086
+ });
37087
+ this.popupSubs = this.popupRef.popup.instance.anchorViewportLeave.subscribe(() => {
37088
+ this.popupSubs?.unsubscribe();
37089
+ this.popupSubs = null;
37090
+ this.closePopup();
37091
+ });
37092
+ this.initPopupProperties();
37093
+ }
37094
+ setPopupAttributes() {
37095
+ const popupElement = this.popupRef.popupElement;
37096
+ const popupId = `k-group-tool-${this.nextId}-popup`;
37097
+ const popupAriaElement = popupElement.querySelector('.k-popup');
37098
+ this.renderer.setAttribute(popupElement, 'dir', this.ctx.localization.rtl ? 'rtl' : 'ltr');
37099
+ this.renderer.setAttribute(popupAriaElement, 'id', popupId);
37100
+ this.renderer.setAttribute(popupAriaElement, 'role', 'dialog');
37101
+ this.buttonElement?.setAttribute('aria-expanded', 'true');
37102
+ this.buttonElement?.setAttribute('aria-controls', popupId);
37103
+ }
37104
+ initPopupProperties() {
37105
+ this.popupRef.content.instance.ctx = this.ctx;
37106
+ this.popupRef.content.instance.hostButton = this.host;
37107
+ this.popupSubs.add(this.popupRef.content.instance.groupClear.subscribe(() => {
37108
+ this.closePopup();
37109
+ }));
37110
+ this.popupSubs.add(this.popupRef.content.instance.close.subscribe(() => {
37111
+ this.closePopup();
37112
+ }));
37113
+ }
37114
+ closePopup() {
37115
+ this.buttonElement?.setAttribute('aria-expanded', 'false');
37116
+ this.buttonElement?.removeAttribute('aria-controls');
37117
+ this.host.selected = false;
37118
+ if (this.popupRef) {
37119
+ this.popupRef.close();
37120
+ this.popupRef = null;
37121
+ }
37122
+ if (this.popupSubs) {
37123
+ this.popupSubs.unsubscribe();
37124
+ this.popupSubs = null;
37125
+ }
37126
+ if (this.removeClickListener) {
37127
+ this.removeClickListener();
37128
+ this.removeClickListener = null;
37129
+ }
37130
+ }
37131
+ get buttonElement() {
37132
+ return this.host.getButton();
37133
+ }
37134
+ isGroupingApplied(group) {
37135
+ return isPresent$1(group) && group.length > 0;
37136
+ }
37137
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupCommandToolbarDirective, deps: [{ token: i54.ToolBarButtonComponent }, { token: i2.PopupService }, { token: ContextService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: AdaptiveGridService }], target: i0.ɵɵFactoryTarget.Directive });
37138
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupCommandToolbarDirective, isStandalone: true, selector: "[kendoGridGroupTool]", ngImport: i0 });
37139
+ }
37140
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupCommandToolbarDirective, decorators: [{
37141
+ type: Directive,
37142
+ args: [{
37143
+ selector: '[kendoGridGroupTool]',
37144
+ standalone: true
37145
+ }]
37146
+ }], ctorParameters: function () { return [{ type: i54.ToolBarButtonComponent }, { type: i2.PopupService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: AdaptiveGridService }]; } });
37147
+
37148
+ /**
37149
+ * Stores the row and cell highlight state of the Grid.
37150
+ *
37151
+ * @example
37152
+ * ```typescript
37153
+ * <kendo-grid kendoGridHighlight="ProductID"></kendo-grid>
37154
+ *
37155
+ * <kendo-grid [kendoGridHighlight]="myKey"></kendo-grid>
37156
+ * ```
37157
+ * @remarks
37158
+ * Applied to: {@link GridComponent}.
37159
+ */
37160
+ class HighlightDirective {
37161
+ ctx;
37162
+ /**
37163
+ * Stores the highlighted items keys.
37164
+ * @default []
37165
+ */
37166
+ highlightedKeys = [];
37167
+ /**
37168
+ * Sets the item key to store in `highlightedKeys`. The Grid uses the row index as the default item key.
37169
+ */
37170
+ highlightItemKey;
37171
+ /**
37172
+ * Sets the column key for a data cell. The Grid uses the column index as the default column key.
37173
+ */
37174
+ highlightColumnKey;
37175
+ rowHighlightState = new Set();
37176
+ cellHighlightState = new PairSet();
37177
+ constructor(ctx) {
37178
+ this.ctx = ctx;
37179
+ this.ctx.highlightDirective = this;
37180
+ }
37181
+ ngOnChanges(changes) {
37182
+ if (isPresent$1(changes['highlightedKeys'])) {
37183
+ this.setState(this.highlightedKeys);
37184
+ }
37185
+ }
37186
+ ngOnDestroy() {
37187
+ this.reset();
37188
+ this.ctx.highlightDirective = null;
37189
+ }
37190
+ /**
37191
+ * @hidden
37192
+ */
37193
+ isRowHighlighted(row) {
37194
+ return this.rowHighlightState.has(this.getItemKey(row));
37195
+ }
37196
+ /**
37197
+ * @hidden
37198
+ */
37199
+ isCellHighlighted(row, column, colIndex) {
37200
+ const highlightItem = this.getHighlightItem(row, column, colIndex);
37201
+ return this.cellHighlightState.has(highlightItem.itemKey, highlightItem.columnKey);
37202
+ }
37203
+ getItemKey(row) {
37204
+ if (this.highlightItemKey) {
37205
+ if (typeof this.highlightItemKey === "string") {
37206
+ return row.data?.[this.highlightItemKey];
37207
+ }
37208
+ if (typeof this.highlightItemKey === "function") {
37209
+ return this.highlightItemKey(row);
37210
+ }
37211
+ }
37212
+ return row.index;
37213
+ }
37214
+ getHighlightItem(row, col, colIndex) {
37215
+ const itemIdentifiers = {};
37216
+ itemIdentifiers.itemKey = this.getItemKey(row);
37217
+ if (!isPresent$1(col) && !isPresent$1(colIndex)) {
37218
+ return itemIdentifiers;
37219
+ }
37220
+ if (this.highlightColumnKey) {
37221
+ if (typeof this.highlightColumnKey === "string") {
37222
+ itemIdentifiers.columnKey = row.dataItem[this.highlightColumnKey];
37223
+ }
37224
+ if (typeof this.highlightColumnKey === "function") {
37225
+ itemIdentifiers.columnKey = this.highlightColumnKey(col, colIndex);
37226
+ }
37227
+ }
37228
+ return {
37229
+ itemKey: itemIdentifiers.itemKey,
37230
+ columnKey: itemIdentifiers.columnKey ? itemIdentifiers.columnKey : colIndex
37231
+ };
37232
+ }
37233
+ setState(highlightedKeys) {
37234
+ this.reset();
37235
+ if (!highlightedKeys || highlightedKeys.length === 0) {
37236
+ return;
37237
+ }
37238
+ const rowHighlights = highlightedKeys.filter(item => !isPresent$1(item.columnKey));
37239
+ const cellHighlights = highlightedKeys.filter(item => isPresent$1(item.columnKey));
37240
+ if (cellHighlights.length > 0) {
37241
+ this.cellHighlightState = new PairSet(cellHighlights, 'itemKey', 'columnKey');
37242
+ }
37243
+ if (rowHighlights.length > 0) {
37244
+ rowHighlights.forEach(item => {
37245
+ this.rowHighlightState.add(item.itemKey);
37246
+ });
37247
+ }
37248
+ }
37249
+ reset() {
37250
+ this.rowHighlightState.clear();
37251
+ this.cellHighlightState.clear();
37252
+ }
37253
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HighlightDirective, deps: [{ token: ContextService }], target: i0.ɵɵFactoryTarget.Directive });
37254
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: HighlightDirective, isStandalone: true, selector: "[kendoGridHighlight]", inputs: { highlightedKeys: "highlightedKeys", highlightItemKey: ["kendoGridHighlight", "highlightItemKey"], highlightColumnKey: "highlightColumnKey" }, usesOnChanges: true, ngImport: i0 });
37441
37255
  }
37442
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterCommandToolbarDirective, decorators: [{
37256
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HighlightDirective, decorators: [{
37443
37257
  type: Directive,
37444
37258
  args: [{
37445
- selector: '[kendoGridFilterTool]',
37259
+ selector: '[kendoGridHighlight]',
37446
37260
  standalone: true
37447
37261
  }]
37448
- }], ctorParameters: function () { return [{ type: i54.ToolBarButtonComponent }, { type: i2.PopupService }, { type: ContextService }, { type: FilterService }, { type: ColumnInfoService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: AdaptiveGridService }]; } });
37262
+ }], ctorParameters: function () { return [{ type: ContextService }]; }, propDecorators: { highlightedKeys: [{
37263
+ type: Input
37264
+ }], highlightItemKey: [{
37265
+ type: Input,
37266
+ args: ["kendoGridHighlight"]
37267
+ }], highlightColumnKey: [{
37268
+ type: Input
37269
+ }] } });
37449
37270
 
37450
37271
  /**
37451
- * Represents the `edit` command in the Grid. Apply this directive to any `kendo-toolbar-button`
37452
- * element inside a ToolbarComponent used in the Grid.
37453
- *
37454
- * When you click the toolbar button with this directive, the
37455
- * [`edit`]({% slug api_grid_gridcomponent %}#toc-edit) event fires.
37456
- *
37457
- * @example
37458
- * ```html
37459
- * <kendo-grid>
37460
- * <kendo-toolbar>
37461
- * <kendo-toolbar-button text="Edit" kendoGridEditTool></kendo-toolbar-button>
37462
- * </kendo-toolbar>
37463
- * </kendo-grid>
37464
- * ```
37465
- * @remarks
37466
- * Applied to: {@link ToolBarButtonComponent}.
37272
+ * @hidden
37467
37273
  */
37468
- class EditCommandToolbarDirective extends ToolbarEditingToolBase {
37469
- editService;
37470
- constructor(editService, host, selection, ctx, zone, cdr) {
37471
- super(host, ToolbarToolName.edit, ctx, zone, cdr, editService, selection);
37472
- this.editService = editService;
37473
- }
37274
+ const DEFAULT_AI_REQUEST_OPTIONS = {
37275
+ headers: new HttpHeaders({
37276
+ 'Content-Type': 'application/json'
37277
+ }),
37278
+ role: 'user',
37279
+ method: 'POST',
37280
+ responseType: 'json'
37281
+ };
37282
+ /**
37283
+ * Represents the event data when the AI Assistant request completes successfully.
37284
+ */
37285
+ class GridToolbarAIResponseSuccessEvent extends PreventableEvent$1 {
37474
37286
  /**
37475
- * @hidden
37287
+ * The HTTP response from the AI service.
37476
37288
  */
37477
- onClick(e) {
37478
- e.preventDefault();
37479
- if (!this.isSelectionPresent) {
37480
- return;
37481
- }
37482
- this.editService.beginEdit(this.lastSelectionIndex);
37289
+ response;
37290
+ constructor(response) {
37291
+ super();
37292
+ this.response = response;
37483
37293
  }
37484
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EditCommandToolbarDirective, deps: [{ token: EditService }, { token: i54.ToolBarButtonComponent }, { token: SelectionService }, { token: ContextService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
37485
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: EditCommandToolbarDirective, isStandalone: true, selector: "[kendoGridEditTool]", usesInheritance: true, ngImport: i0 });
37486
37294
  }
37487
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EditCommandToolbarDirective, decorators: [{
37488
- type: Directive,
37489
- args: [{
37490
- selector: '[kendoGridEditTool]',
37491
- standalone: true
37492
- }]
37493
- }], ctorParameters: function () { return [{ type: EditService }, { type: i54.ToolBarButtonComponent }, { type: SelectionService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; } });
37494
-
37495
37295
  /**
37496
- * Represents the `save` command in the Grid. Apply this directive to any `kendo-toolbar-button`
37497
- * element inside a ToolbarComponent used in the Grid.
37498
- *
37499
- * When you click the toolbar button with this directive, the
37500
- * [`save`]({% slug api_grid_gridcomponent %}#toc-save) event fires.
37501
- *
37502
- * @example
37503
- * ```html
37504
- * <kendo-grid>
37505
- * <kendo-toolbar>
37506
- * <kendo-toolbar-button text="Save" kendoGridSaveTool></kendo-toolbar-button>
37507
- * </kendo-toolbar>
37508
- * </kendo-grid>
37509
- * ```
37510
- * @remarks
37511
- * Applied to: {@link ToolBarButtonComponent}.
37296
+ * Represents the event data when the AI Assistant request completes with an error.
37512
37297
  */
37513
- class SaveCommandToolbarDirective extends ToolbarEditingToolBase {
37514
- editService;
37515
- constructor(editService, host, selection, ctx, zone, cdr) {
37516
- super(host, ToolbarToolName.save, ctx, zone, cdr, editService, selection);
37517
- this.editService = editService;
37518
- }
37298
+ class GridToolbarAIResponseErrorEvent extends PreventableEvent$1 {
37519
37299
  /**
37520
- * @hidden
37300
+ * The HTTP error response from the AI service.
37521
37301
  */
37522
- onClick(e) {
37523
- e.preventDefault();
37524
- if (this.editService.hasNewItem) {
37525
- this.editService.save();
37526
- }
37527
- else if (this.isSelectionPresent && this.editService.isEdited(this.lastSelectionIndex)) {
37528
- this.editService.save(this.lastSelectionIndex);
37529
- }
37530
- else {
37531
- this.editService.editedIndices.forEach(i => this.editService.save(i.index));
37532
- }
37302
+ error;
37303
+ constructor(error) {
37304
+ super();
37305
+ this.error = error;
37533
37306
  }
37534
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SaveCommandToolbarDirective, deps: [{ token: EditService }, { token: i54.ToolBarButtonComponent }, { token: SelectionService }, { token: ContextService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
37535
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: SaveCommandToolbarDirective, isStandalone: true, selector: "[kendoGridSaveTool]", usesInheritance: true, ngImport: i0 });
37536
37307
  }
37537
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SaveCommandToolbarDirective, decorators: [{
37538
- type: Directive,
37539
- args: [{
37540
- selector: '[kendoGridSaveTool]',
37541
- standalone: true
37542
- }]
37543
- }], ctorParameters: function () { return [{ type: EditService }, { type: i54.ToolBarButtonComponent }, { type: SelectionService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; } });
37544
37308
 
37545
37309
  /**
37546
- * Represents the `remove` command in the Grid. Apply this directive to any `kendo-toolbar-button`
37547
- * element inside a ToolbarComponent used in the Grid.
37548
- *
37549
- * When you click the toolbar button with this directive, the
37550
- * [`remove`]({% slug api_grid_gridcomponent %}#toc-remove) event fires.
37551
- *
37552
- * @example
37553
- * ```html
37554
- * <kendo-grid>
37555
- * <kendo-toolbar>
37556
- * <kendo-toolbar-button text="Remove row" kendoGridRemoveTool></kendo-toolbar-button>
37557
- * </kendo-toolbar>
37558
- * </kendo-grid>
37559
- * ```
37560
- * @remarks
37561
- * Applied to: {@link ToolBarButtonComponent}.
37310
+ * @hidden
37311
+ * Converts date strings in a filter to Date objects.
37562
37312
  */
37563
- class RemoveCommandToolbarDirective extends ToolbarEditingToolBase {
37564
- editService;
37565
- selection;
37566
- constructor(editService, host, selection, ctx, zone, cdr) {
37567
- super(host, ToolbarToolName.remove, ctx, zone, cdr, editService, selection);
37568
- this.editService = editService;
37569
- this.selection = selection;
37313
+ const convertDateStringsInFilter = (filter) => {
37314
+ if (!filter) {
37315
+ return filter;
37570
37316
  }
37571
- /**
37572
- * @hidden
37573
- */
37574
- onClick(e) {
37575
- e.preventDefault();
37576
- if (this.isSelectionPresent) {
37577
- this.editService.remove(this.lastSelectionIndex);
37317
+ if (filter.filters && Array.isArray(filter.filters)) {
37318
+ return {
37319
+ ...filter,
37320
+ filters: filter.filters.map(f => convertDateStringsInFilter(f))
37321
+ };
37322
+ }
37323
+ if (filter.field && filter.value !== undefined) {
37324
+ if (typeof filter.value === 'string' && isDateOperator(filter.operator)) {
37325
+ const date = parseDate(filter.value);
37326
+ return {
37327
+ ...filter,
37328
+ value: date || filter.value
37329
+ };
37578
37330
  }
37579
37331
  }
37580
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RemoveCommandToolbarDirective, deps: [{ token: EditService }, { token: i54.ToolBarButtonComponent }, { token: SelectionService }, { token: ContextService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
37581
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: RemoveCommandToolbarDirective, isStandalone: true, selector: "[kendoGridRemoveTool]", usesInheritance: true, ngImport: i0 });
37582
- }
37583
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RemoveCommandToolbarDirective, decorators: [{
37584
- type: Directive,
37585
- args: [{
37586
- selector: '[kendoGridRemoveTool]',
37587
- standalone: true
37588
- }]
37589
- }], ctorParameters: function () { return [{ type: EditService }, { type: i54.ToolBarButtonComponent }, { type: SelectionService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; } });
37332
+ return filter;
37333
+ };
37334
+ /**
37335
+ * @hidden
37336
+ */
37337
+ const isDateOperator = (operator) => {
37338
+ const dateOperators = [
37339
+ 'eq', 'neq', 'lt', 'lte', 'gt', 'gte'
37340
+ ];
37341
+ return dateOperators.includes(operator);
37342
+ };
37343
+ /**
37344
+ * @hidden
37345
+ * Processes cell highlights for a specific filter and item.
37346
+ */
37347
+ const processCellHighlights = (filter, rowIndex, columns, highlightItems) => {
37348
+ Object.keys(filter.cells).forEach((columnField) => {
37349
+ const actualColumnIndex = Array.from(columns).findIndex((col) => col.field === columnField);
37350
+ if (actualColumnIndex !== -1) {
37351
+ highlightItems.push({
37352
+ itemKey: rowIndex,
37353
+ columnKey: actualColumnIndex,
37354
+ });
37355
+ }
37356
+ });
37357
+ };
37358
+ /**
37359
+ * @hidden
37360
+ * Processes filtered results and adds highlight items.
37361
+ */
37362
+ const processFilteredResults = (filteredResults, data, filter, columns, highlightItems) => {
37363
+ filteredResults?.forEach((item) => {
37364
+ const rowIndex = data.findIndex((dataItem) => dataItem === item);
37365
+ if (filter.cells && Object.keys(filter.cells).length > 0) {
37366
+ processCellHighlights(filter, rowIndex, columns, highlightItems);
37367
+ }
37368
+ else {
37369
+ highlightItems.push({
37370
+ itemKey: rowIndex,
37371
+ });
37372
+ }
37373
+ });
37374
+ };
37375
+ /**
37376
+ * @hidden
37377
+ * Highlights items in a grid based on the provided filters and columns.
37378
+ * @param data - The data to be highlighted.
37379
+ * @param filters - The composite highlight descriptors containing the filters and logic.
37380
+ * @param columns - The columns of the grid.
37381
+ * @returns An array of HighlightItem objects representing the highlighted items.
37382
+ */
37383
+ const highlightBy = (data, filters, columns) => {
37384
+ const highlightItems = [];
37385
+ filters.forEach((filter) => {
37386
+ const processedFilters = filter.filters.map((filter) => convertDateStringsInFilter(filter));
37387
+ const filteredResults = filterBy(data, {
37388
+ logic: filter.logic || "and",
37389
+ filters: processedFilters,
37390
+ });
37391
+ processFilteredResults(filteredResults, data, filter, columns, highlightItems);
37392
+ });
37393
+ return highlightItems;
37394
+ };
37590
37395
 
37591
37396
  /**
37592
- * Represents the `cancel` command in the Grid.
37593
- * Apply this directive to any `kendo-toolbar-button` element inside a ToolbarComponent in the Grid.
37594
- *
37595
- * When you click the toolbar button with this directive, the [`cancel`]({% slug api_grid_gridcomponent %}#toc-cancel) event triggers.
37596
- *
37597
- * @example
37598
- * ```html
37599
- * <kendo-grid>
37600
- * <kendo-toolbar>
37601
- * <kendo-toolbar-button text="Cancel" kendoGridCancelTool></kendo-toolbar-button>
37602
- * </kendo-toolbar>
37603
- * </kendo-grid>
37604
- * ```
37605
- * @remarks
37606
- * Applied to: {@link ToolBarButtonComponent}.
37397
+ * @hidden
37607
37398
  */
37608
- class CancelCommandToolbarDirective extends ToolbarEditingToolBase {
37609
- editService;
37610
- constructor(editService, host, selection, ctx, zone, cdr) {
37611
- super(host, ToolbarToolName.cancel, ctx, zone, cdr, editService, selection);
37612
- this.editService = editService;
37399
+ class AiAssistantComponent {
37400
+ http;
37401
+ ctx;
37402
+ columnInfoService;
37403
+ aiPrompt;
37404
+ activeView = 0;
37405
+ requestUrl;
37406
+ requestOptions;
37407
+ aiPromptSettings;
37408
+ aiToolDirective;
37409
+ streaming = false;
37410
+ disabledGenerateButton = false;
37411
+ lastMessage;
37412
+ requestData;
37413
+ currentRequestSubscription = null;
37414
+ //Remove this when the AI Assistant has a built-in loading indicator
37415
+ loadingOutput = { id: 'k-loading-item', output: '', prompt: '' };
37416
+ columns = [];
37417
+ idCounter = 0;
37418
+ constructor(http, ctx, columnInfoService) {
37419
+ this.http = http;
37420
+ this.ctx = ctx;
37421
+ this.columnInfoService = columnInfoService;
37613
37422
  }
37614
- /**
37615
- * @hidden
37616
- */
37617
- onClick(e) {
37618
- e.preventDefault();
37619
- if (this.editService.hasNewItem) {
37620
- this.editService.endEdit();
37423
+ ngAfterViewInit() {
37424
+ this.columns = this.columnInfoService.leafNamedColumns.map((col) => ({ field: col.field }));
37425
+ }
37426
+ ngOnDestroy() {
37427
+ this.unsubscribeCurrentRequest();
37428
+ }
37429
+ message(message) {
37430
+ return this.ctx.localization.get(message);
37431
+ }
37432
+ cancelRequest() {
37433
+ this.aiToolDirective.cancelRequest.emit();
37434
+ this.unsubscribeCurrentRequest();
37435
+ this.streaming = false;
37436
+ }
37437
+ onPromptRequest(ev) {
37438
+ if (this.aiToolDirective.promptOutputs.length === 0) {
37439
+ this.aiToolDirective.promptOutputs.push(this.loadingOutput);
37621
37440
  }
37622
- else if (this.isSelectionPresent && this.editService.isEdited(this.lastSelectionIndex)) {
37623
- this.editService.endEdit(this.lastSelectionIndex);
37441
+ this.unsubscribeCurrentRequest();
37442
+ this.streaming = true;
37443
+ this.activeView = 1;
37444
+ if (ev.prompt) {
37445
+ this.lastMessage = ev.prompt;
37624
37446
  }
37625
- else {
37626
- this.editService.editedIndices.forEach(i => this.editService.endEdit(i.index));
37447
+ this.requestData = {
37448
+ columns: this.columns,
37449
+ promptMessage: ev.prompt,
37450
+ url: this.requestUrl,
37451
+ requestOptions: {
37452
+ ...this.requestOptions
37453
+ }
37454
+ };
37455
+ if (!this.requestOptions.body) {
37456
+ const requestBody = {
37457
+ role: this.requestData.requestOptions.role,
37458
+ contents: [
37459
+ {
37460
+ text: this.requestData.promptMessage
37461
+ }
37462
+ ],
37463
+ columns: this.requestData.columns
37464
+ };
37465
+ this.requestData.requestOptions.body = requestBody;
37466
+ }
37467
+ this.aiToolDirective.promptRequest.emit({ requestData: this.requestData, isRetry: ev.isRetry });
37468
+ if (!this.requestUrl) {
37469
+ return;
37627
37470
  }
37471
+ this.currentRequestSubscription = this.sendPromptRequest().subscribe((res) => {
37472
+ if (res.body) {
37473
+ this.processResponse(res);
37474
+ this.streaming = false;
37475
+ }
37476
+ this.currentRequestSubscription = null;
37477
+ }, (error) => {
37478
+ this.handleError(error);
37479
+ this.streaming = false;
37480
+ this.currentRequestSubscription = null;
37481
+ });
37628
37482
  }
37629
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CancelCommandToolbarDirective, deps: [{ token: EditService }, { token: i54.ToolBarButtonComponent }, { token: SelectionService }, { token: ContextService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
37630
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CancelCommandToolbarDirective, isStandalone: true, selector: "[kendoGridCancelTool]", usesInheritance: true, ngImport: i0 });
37483
+ sendPromptRequest() {
37484
+ const request = new HttpRequest(this.requestData.requestOptions.method, this.requestData.url, this.requestData.requestOptions.body, this.requestData.requestOptions);
37485
+ return this.http.request(request);
37486
+ }
37487
+ processResponse(response) {
37488
+ if (this.aiToolDirective.autoClose) {
37489
+ this.aiToolDirective.emitOpenClose = true;
37490
+ this.aiToolDirective.toggleWindow();
37491
+ }
37492
+ const responseBody = response.body;
37493
+ const responseSuccessEvent = new GridToolbarAIResponseSuccessEvent(response);
37494
+ this.aiToolDirective.responseSuccess.emit(responseSuccessEvent);
37495
+ if (responseSuccessEvent.isDefaultPrevented()) {
37496
+ this.deleteLoadingOutput();
37497
+ return;
37498
+ }
37499
+ const isFilterable = Boolean(this.ctx.grid.filterable);
37500
+ const isSortable = Boolean(this.ctx.grid.sortable);
37501
+ const isGroupable = Boolean(this.ctx.grid.groupable);
37502
+ if (isFilterable && responseBody.filter) {
37503
+ this.processFilterResponse(responseBody.filter);
37504
+ }
37505
+ if (isSortable && responseBody.sort) {
37506
+ this.processArrayResponse(responseBody.sort, this.ctx.grid.currentState.sort || [], (item) => item.field, (mergedArray) => this.ctx.grid.sortChange.next(mergedArray));
37507
+ }
37508
+ if (isGroupable && responseBody.group) {
37509
+ this.processArrayResponse(responseBody.group, this.ctx.grid.currentState.group || [], (item) => item.field, (mergedArray) => this.ctx.grid.groupChange.next(mergedArray));
37510
+ }
37511
+ if (this.ctx.highlightDirective && responseBody.highlight) {
37512
+ this.processHighlightResponse(responseBody.highlight);
37513
+ }
37514
+ const responseContentStart = [`${this.ctx.localization.get('aiAssistantOutputCardBodyContent')} \n`];
37515
+ const responseContentBody = responseBody.messages
37516
+ .map((output, idx) => `${idx + 1} ${output}`)
37517
+ .join('\n');
37518
+ const output = {
37519
+ id: this.idCounter++,
37520
+ title: this.ctx.localization.get('aiAssistantOutputCardTitle'),
37521
+ prompt: this.lastMessage,
37522
+ output: responseContentStart.concat(responseContentBody).join(''),
37523
+ };
37524
+ this.deleteLoadingOutput();
37525
+ this.aiToolDirective.promptOutputs.unshift(output);
37526
+ }
37527
+ handleError(error) {
37528
+ const responseErrorEvent = new GridToolbarAIResponseErrorEvent(error);
37529
+ this.aiToolDirective.responseError.emit(responseErrorEvent);
37530
+ if (responseErrorEvent.isDefaultPrevented()) {
37531
+ this.deleteLoadingOutput();
37532
+ return;
37533
+ }
37534
+ const output = {
37535
+ id: this.idCounter++,
37536
+ prompt: this.lastMessage,
37537
+ output: error.message
37538
+ };
37539
+ this.deleteLoadingOutput();
37540
+ this.aiToolDirective.promptOutputs.unshift(output);
37541
+ }
37542
+ deleteLoadingOutput() {
37543
+ if (this.aiToolDirective.promptOutputs[0]?.id === this.loadingOutput.id) {
37544
+ this.aiToolDirective.promptOutputs.splice(0, 1);
37545
+ }
37546
+ }
37547
+ unsubscribeCurrentRequest() {
37548
+ if (this.currentRequestSubscription) {
37549
+ this.currentRequestSubscription.unsubscribe();
37550
+ this.currentRequestSubscription = null;
37551
+ }
37552
+ }
37553
+ processArrayResponse(newItems, currentItems, getField, updateGrid) {
37554
+ if (newItems?.length === 0) {
37555
+ updateGrid([]);
37556
+ }
37557
+ else if (newItems?.length) {
37558
+ let mergedArray = [...newItems];
37559
+ const newFields = newItems.map(getField);
37560
+ const existingItemsToKeep = currentItems.filter(item => !newFields.includes(getField(item)));
37561
+ mergedArray = [...mergedArray, ...existingItemsToKeep];
37562
+ updateGrid(mergedArray);
37563
+ }
37564
+ }
37565
+ processHighlightResponse(highlight) {
37566
+ if (highlight.length === 0) {
37567
+ this.ctx.highlightDirective['setState']([]);
37568
+ return;
37569
+ }
37570
+ const highlightedItems = highlightBy(this.ctx.dataBindingDirective['originalData'], highlight, this.columns);
37571
+ this.ctx.highlightDirective['setState'](highlightedItems);
37572
+ }
37573
+ processFilterResponse(filter) {
37574
+ const processedFilter = convertDateStringsInFilter(filter);
37575
+ const clearFilter = Object.keys(processedFilter).length === 0;
37576
+ if (clearFilter) {
37577
+ this.ctx.grid.filterChange.next(undefined);
37578
+ }
37579
+ else if (processedFilter?.filters.length) {
37580
+ const currentFilter = this.ctx.grid.currentState.filter;
37581
+ let mergedFilter = processedFilter;
37582
+ if (currentFilter && currentFilter.filters?.length > 0) {
37583
+ mergedFilter = {
37584
+ logic: 'and',
37585
+ filters: [
37586
+ currentFilter,
37587
+ processedFilter
37588
+ ]
37589
+ };
37590
+ }
37591
+ this.ctx.grid.filterChange.next(mergedFilter);
37592
+ }
37593
+ }
37594
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AiAssistantComponent, deps: [{ token: i1$8.HttpClient }, { token: ContextService }, { token: ColumnInfoService }], target: i0.ɵɵFactoryTarget.Component });
37595
+ 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: `
37596
+ <kendo-aiprompt
37597
+ #aiPrompt
37598
+ [promptSuggestions]="aiPromptSettings?.promptSuggestions"
37599
+ [showOutputRating]="aiPromptSettings?.showOutputRating"
37600
+ [streaming]="streaming"
37601
+ [speechToTextButton]="aiPromptSettings?.speechToTextButton"
37602
+ [(activeView)]="activeView"
37603
+ [generateButtonSVGIcon]="aiPromptSettings?.generateButtonSVGIcon"
37604
+ [generateButtonIcon]="aiPromptSettings?.generateButtonIcon"
37605
+ [disabledGenerateButton]="disabledGenerateButton || promptView.textAreaValue?.length === 0"
37606
+ [promptOutputs]="aiPromptSettings?.promptOutputs"
37607
+ [textAreaSettings]="aiPromptSettings?.textAreaSettings"
37608
+ (promptRequest)="onPromptRequest($event)"
37609
+ (promptRequestCancel)="cancelRequest()"
37610
+ >
37611
+ <kendo-aiprompt-prompt-view #promptView></kendo-aiprompt-prompt-view>
37612
+ <kendo-aiprompt-output-view></kendo-aiprompt-output-view>
37613
+ <ng-template *ngIf="streaming && aiPrompt.streaming" kendoAIPromptOutputTemplate let-output>
37614
+ <div class="k-card">
37615
+ <div class="k-card-header">
37616
+ <div class="k-card-title">
37617
+ <span class="k-skeleton k-skeleton-text k-skeleton-pulse" [style.width.px]="200"></span>
37618
+ </div>
37619
+ <div class="k-card-subtitle">
37620
+ <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
37621
+ </div>
37622
+ </div>
37623
+ <div class="k-card-body">
37624
+ <span class="k-skeleton k-skeleton-rect k-skeleton-pulse" style="height: 80px;"></span>
37625
+ </div>
37626
+ <div class="k-card-actions">
37627
+ <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
37628
+ </div>
37629
+ </div>
37630
+ </ng-template>
37631
+ <ng-template *ngIf="!(streaming && aiPrompt.streaming)" kendoAIPromptOutputBodyTemplate let-output>
37632
+ <p>{{output.output}}</p>
37633
+ </ng-template>
37634
+ <kendo-aiprompt-messages
37635
+ [generateOutput]="message('aiAssistantApplyButtonText')"
37636
+ ></kendo-aiprompt-messages>
37637
+ </kendo-aiprompt>
37638
+ `, 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]" }] });
37631
37639
  }
37632
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CancelCommandToolbarDirective, decorators: [{
37633
- type: Directive,
37640
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AiAssistantComponent, decorators: [{
37641
+ type: Component,
37634
37642
  args: [{
37635
- selector: '[kendoGridCancelTool]',
37636
- standalone: true
37643
+ standalone: true,
37644
+ imports: [NgIf, AIPromptComponent, AIPromptCustomMessagesComponent, PromptViewComponent, OutputViewComponent, AIPromptOutputTemplateDirective, AIPromptOutputBodyTemplateDirective],
37645
+ template: `
37646
+ <kendo-aiprompt
37647
+ #aiPrompt
37648
+ [promptSuggestions]="aiPromptSettings?.promptSuggestions"
37649
+ [showOutputRating]="aiPromptSettings?.showOutputRating"
37650
+ [streaming]="streaming"
37651
+ [speechToTextButton]="aiPromptSettings?.speechToTextButton"
37652
+ [(activeView)]="activeView"
37653
+ [generateButtonSVGIcon]="aiPromptSettings?.generateButtonSVGIcon"
37654
+ [generateButtonIcon]="aiPromptSettings?.generateButtonIcon"
37655
+ [disabledGenerateButton]="disabledGenerateButton || promptView.textAreaValue?.length === 0"
37656
+ [promptOutputs]="aiPromptSettings?.promptOutputs"
37657
+ [textAreaSettings]="aiPromptSettings?.textAreaSettings"
37658
+ (promptRequest)="onPromptRequest($event)"
37659
+ (promptRequestCancel)="cancelRequest()"
37660
+ >
37661
+ <kendo-aiprompt-prompt-view #promptView></kendo-aiprompt-prompt-view>
37662
+ <kendo-aiprompt-output-view></kendo-aiprompt-output-view>
37663
+ <ng-template *ngIf="streaming && aiPrompt.streaming" kendoAIPromptOutputTemplate let-output>
37664
+ <div class="k-card">
37665
+ <div class="k-card-header">
37666
+ <div class="k-card-title">
37667
+ <span class="k-skeleton k-skeleton-text k-skeleton-pulse" [style.width.px]="200"></span>
37668
+ </div>
37669
+ <div class="k-card-subtitle">
37670
+ <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
37671
+ </div>
37672
+ </div>
37673
+ <div class="k-card-body">
37674
+ <span class="k-skeleton k-skeleton-rect k-skeleton-pulse" style="height: 80px;"></span>
37675
+ </div>
37676
+ <div class="k-card-actions">
37677
+ <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
37678
+ </div>
37679
+ </div>
37680
+ </ng-template>
37681
+ <ng-template *ngIf="!(streaming && aiPrompt.streaming)" kendoAIPromptOutputBodyTemplate let-output>
37682
+ <p>{{output.output}}</p>
37683
+ </ng-template>
37684
+ <kendo-aiprompt-messages
37685
+ [generateOutput]="message('aiAssistantApplyButtonText')"
37686
+ ></kendo-aiprompt-messages>
37687
+ </kendo-aiprompt>
37688
+ `
37637
37689
  }]
37638
- }], ctorParameters: function () { return [{ type: EditService }, { type: i54.ToolBarButtonComponent }, { type: SelectionService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; } });
37690
+ }], ctorParameters: function () { return [{ type: i1$8.HttpClient }, { type: ContextService }, { type: ColumnInfoService }]; }, propDecorators: { aiPrompt: [{
37691
+ type: ViewChild,
37692
+ args: [AIPromptComponent]
37693
+ }] } });
37639
37694
 
37640
- let incrementingId = 0;
37641
37695
  /**
37642
- * Represents the toolbar tool for grouping columns of the Grid.
37696
+ * Represents an AI Assistant tool of the Grid.
37643
37697
  * Use this directive on any `kendo-toolbar-button` inside a ToolbarComponent in the Grid.
37644
- * When you click the toolbar button with this directive, the `group` event is triggered.
37645
37698
  *
37646
37699
  * @example
37647
- * ```html
37700
+ * ```html-no-run
37648
37701
  * <kendo-grid>
37649
37702
  * <kendo-toolbar>
37650
- * <kendo-toolbar-button text="Group" kendoGridGroupTool></kendo-toolbar-button>
37703
+ * <kendo-toolbar-button kendoGridAIAssistantTool></kendo-toolbar-button>
37651
37704
  * </kendo-toolbar>
37652
37705
  * </kendo-grid>
37653
37706
  * ```
37654
37707
  * @remarks
37655
37708
  * Applied to: {@link ToolBarButtonComponent}.
37656
37709
  */
37657
- class GroupCommandToolbarDirective {
37710
+ class AIAssistantToolbarDirective extends ToolbarToolBase {
37711
+ windowService;
37658
37712
  host;
37659
- popupService;
37660
37713
  ctx;
37661
- ngZone;
37662
- renderer;
37663
- adaptiveGridService;
37664
- popupRef;
37665
- nextId = incrementingId++;
37666
- toolSubs = new Subscription();
37667
- popupSubs;
37668
- actionSheetCloseSub;
37669
- removeClickListener;
37670
- constructor(host, popupService, ctx, ngZone, renderer, adaptiveGridService) {
37714
+ zone;
37715
+ refresh;
37716
+ /**
37717
+ * The URL to which the AI Assistant tool sends the AI request.
37718
+ * - 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.
37719
+ * - 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.
37720
+ */
37721
+ requestUrl;
37722
+ /**
37723
+ * Configures the request options that the AI Assistant tool sends with the AI request.
37724
+ *
37725
+ * @default { headers: new HttpHeaders({ 'Content-Type': 'application/json' }), role: 'user', method: 'POST', responseType: 'json', withCredentials: false }
37726
+ */
37727
+ requestOptions;
37728
+ /**
37729
+ * Configures the initial settings for the AI Assistant Window when opened.
37730
+ */
37731
+ aiWindowSettings;
37732
+ /**
37733
+ * Configures the initial settings for the AI Prompt component that the AI Assistant Window component uses when opened.
37734
+ */
37735
+ aiPromptSettings;
37736
+ /**
37737
+ * Determines whether to close the AI Assistant Window automatically after a successful request.
37738
+ * @default true
37739
+ */
37740
+ autoClose = true;
37741
+ /**
37742
+ * Determines whether to keep the AI Prompt's outputs after closing the AI Assistant Window.
37743
+ * @default false
37744
+ */
37745
+ keepOutputHistory = false;
37746
+ /**
37747
+ * Emits an event before the AI Assistant tool sends the AI request.
37748
+ * - When you provide a `requestUrl`, you can handle the event to modify the request options.
37749
+ * - When you do not provide a `requestUrl`, you can handle the event to perform an entirely custom request.
37750
+ */
37751
+ promptRequest = new EventEmitter();
37752
+ /**
37753
+ * Emits an event when the user clicks the cancel button.
37754
+ */
37755
+ cancelRequest = new EventEmitter();
37756
+ /**
37757
+ * Emits an event when the AI Assistant tool completes the AI request successfully.
37758
+ * The event contains the response from the AI service and is preventable to allow stopping the default response handling.
37759
+ */
37760
+ responseSuccess = new EventEmitter();
37761
+ /**
37762
+ * Emits an event when the AI Assistant tool completes the AI request with an error.
37763
+ * The event contains the error response from the AI service and is preventable to allow stopping the default error handling.
37764
+ */
37765
+ responseError = new EventEmitter();
37766
+ /**
37767
+ * Emits an event when the AI Assistant tool closes.
37768
+ */
37769
+ close = new EventEmitter();
37770
+ /**
37771
+ * Emits an event when the AI Assistant tool opens.
37772
+ */
37773
+ open = new EventEmitter();
37774
+ tableWizardIcon = tableWizardIcon;
37775
+ emitOpenClose = false;
37776
+ promptOutputs = [];
37777
+ windowRef;
37778
+ subs = new Subscription();
37779
+ defaultAiPromptSettings = {
37780
+ speechToTextButton: true,
37781
+ generateButtonSVGIcon: this.tableWizardIcon,
37782
+ generateButtonIcon: 'table-wizard'
37783
+ };
37784
+ constructor(windowService, host, ctx, zone, refresh, cdr) {
37785
+ super(host, ToolbarToolName.aiAssistant, ctx, zone, cdr);
37786
+ this.windowService = windowService;
37671
37787
  this.host = host;
37672
- this.popupService = popupService;
37673
37788
  this.ctx = ctx;
37674
- this.ngZone = ngZone;
37675
- this.renderer = renderer;
37676
- this.adaptiveGridService = adaptiveGridService;
37789
+ this.zone = zone;
37790
+ this.refresh = refresh;
37791
+ this.host.rounded = 'full';
37792
+ this.host.themeColor = 'primary';
37793
+ this.host.showText = 'never';
37677
37794
  }
37678
37795
  ngOnInit() {
37679
- this.toolSubs = this.host.click.subscribe(e => this.onClick(e));
37680
- this.toolSubs.add(this.ctx.grid.groupChange.subscribe(group => {
37681
- this.host.showBadge = this.isGroupingApplied(group);
37682
- }));
37683
- this.host.hasBadgeContainer = true;
37684
- this.host.showBadge = this.isGroupingApplied(this.ctx.grid.group);
37796
+ this.subs.add(this.host.click.subscribe(() => this.onClick()));
37685
37797
  const hasToolbarIcon = isPresent$1(this.host.toolbarOptions.icon) && this.host.toolbarOptions.icon !== '';
37686
37798
  const hasOverflowIcon = isPresent$1(this.host.overflowOptions.icon) && this.host.overflowOptions.icon !== '';
37687
37799
  const hasIcon = hasToolbarIcon && hasOverflowIcon;
37688
37800
  const hasSvgIcon = isPresent$1(this.host.toolbarOptions.svgIcon) && isPresent$1(this.host.overflowOptions.svgIcon);
37689
37801
  if (!hasIcon) {
37690
- this.host.icon = 'group';
37802
+ this.host.icon = 'sparkles';
37691
37803
  }
37692
37804
  if (!hasSvgIcon) {
37693
- this.host.svgIcon = groupIcon;
37805
+ this.host.svgIcon = sparklesIcon;
37694
37806
  }
37807
+ this.requestOptions = { ...DEFAULT_AI_REQUEST_OPTIONS, ...this.requestOptions };
37695
37808
  }
37696
37809
  ngAfterViewInit() {
37697
- if (!isPresent$1(this.host.text)) {
37698
- this.ngZone.onStable.pipe(take(1)).subscribe(() => {
37699
- this.host.text = this.ctx.localization.get(`groupToolbarToolText`);
37700
- });
37701
- }
37702
- this.buttonElement?.setAttribute('aria-haspopup', 'dialog');
37703
- this.buttonElement?.setAttribute('aria-expanded', 'false');
37704
- this.buttonElement?.setAttribute('title', this.ctx.localization.get('groupToolbarToolText'));
37705
- }
37706
- ngOnDestroy() {
37707
- if (this.toolSubs) {
37708
- this.toolSubs.unsubscribe();
37709
- }
37710
- if (this.popupSubs) {
37711
- this.popupSubs.unsubscribe();
37712
- }
37713
- if (this.popupRef) {
37714
- this.popupRef.close();
37715
- this.popupRef = null;
37716
- }
37717
- if (this.actionSheetCloseSub) {
37718
- this.actionSheetCloseSub.unsubscribe();
37719
- this.actionSheetCloseSub = null;
37720
- }
37721
- if (this.removeClickListener) {
37722
- this.removeClickListener();
37723
- this.removeClickListener = null;
37724
- }
37725
- }
37726
- onClick(e) {
37727
- e.preventDefault();
37728
- if (this.ctx.grid.adaptiveMode === 'auto' && this.adaptiveGridService.windowSize !== 'large') {
37729
- if (!this.ctx.grid.isActionSheetExpanded) {
37730
- this.adaptiveGridService.viewType = 'groupToolbarTool';
37731
- this.ctx.grid.adaptiveRenderer.actionSheet.toggle(true);
37732
- this.host.selected = true;
37733
- this.actionSheetCloseSub = this.ctx.grid.adaptiveRenderer.actionSheet.collapse.subscribe(() => this.host.selected = false);
37734
- }
37735
- }
37736
- else {
37737
- if (this.popupRef) {
37738
- this.closePopup();
37739
- return;
37810
+ super.ngAfterViewInit();
37811
+ this.zone.onStable.pipe(take(1)).subscribe(() => {
37812
+ this.buttonElement?.setAttribute('aria-haspopup', 'dialog');
37813
+ this.buttonElement?.setAttribute('aria-expanded', 'false');
37814
+ const needsTitle = this.host.showText !== 'always' && this.host.showText !== 'toolbar';
37815
+ if (needsTitle && !this.host.title) {
37816
+ this.buttonElement?.setAttribute('title', this.ctx.localization.get('aiAssistantToolbarToolText'));
37740
37817
  }
37741
- this.openPopup();
37742
- }
37743
- }
37744
- openPopup() {
37745
- const direction = this.ctx.localization.rtl ? 'right' : 'left';
37746
- this.popupRef = this.popupService.open({
37747
- anchor: this.buttonElement,
37748
- content: GroupToolbarToolComponent,
37749
- popupClass: 'k-grid-columnmenu-popup',
37750
- positionMode: 'absolute',
37751
- anchorAlign: { vertical: 'bottom', horizontal: direction },
37752
- popupAlign: { vertical: 'top', horizontal: direction }
37753
37818
  });
37754
- this.adaptiveGridService.popupRef = this.popupRef;
37755
- this.setPopupAttributes();
37756
- this.host.selected = true;
37757
- this.ngZone.runOutsideAngular(() => {
37758
- if (!isDocumentAvailable()) {
37759
- return;
37819
+ this.subs.add(this.refresh.onRefresh.pipe(filter((tool) => tool === this.host)).subscribe((tool) => {
37820
+ if (tool.overflows && this.windowRef) {
37821
+ this.windowRef.close();
37760
37822
  }
37761
- this.removeClickListener = this.renderer.listen('document', 'click', (e) => {
37762
- if (this.popupRef && !closest$1(e.target, node => node === this.popupRef.popupElement || node === this.buttonElement)) {
37763
- this.ngZone.run(() => {
37764
- this.closePopup();
37765
- });
37766
- }
37767
- });
37768
- });
37769
- this.popupSubs = this.popupRef.popup.instance.anchorViewportLeave.subscribe(() => {
37770
- this.popupSubs?.unsubscribe();
37771
- this.popupSubs = null;
37772
- this.closePopup();
37773
- });
37774
- this.initPopupProperties();
37775
- }
37776
- setPopupAttributes() {
37777
- const popupElement = this.popupRef.popupElement;
37778
- const popupId = `k-group-tool-${this.nextId}-popup`;
37779
- const popupAriaElement = popupElement.querySelector('.k-popup');
37780
- this.renderer.setAttribute(popupElement, 'dir', this.ctx.localization.rtl ? 'rtl' : 'ltr');
37781
- this.renderer.setAttribute(popupAriaElement, 'id', popupId);
37782
- this.renderer.setAttribute(popupAriaElement, 'role', 'dialog');
37783
- this.buttonElement?.setAttribute('aria-expanded', 'true');
37784
- this.buttonElement?.setAttribute('aria-controls', popupId);
37785
- }
37786
- initPopupProperties() {
37787
- this.popupRef.content.instance.ctx = this.ctx;
37788
- this.popupRef.content.instance.hostButton = this.host;
37789
- this.popupSubs.add(this.popupRef.content.instance.groupClear.subscribe(() => {
37790
- this.closePopup();
37791
37823
  }));
37792
- this.popupSubs.add(this.popupRef.content.instance.close.subscribe(() => {
37793
- this.closePopup();
37794
- }));
37795
- }
37796
- closePopup() {
37797
- this.buttonElement?.setAttribute('aria-expanded', 'false');
37798
- this.buttonElement?.removeAttribute('aria-controls');
37799
- this.host.selected = false;
37800
- if (this.popupRef) {
37801
- this.popupRef.close();
37802
- this.popupRef = null;
37803
- }
37804
- if (this.popupSubs) {
37805
- this.popupSubs.unsubscribe();
37806
- this.popupSubs = null;
37807
- }
37808
- if (this.removeClickListener) {
37809
- this.removeClickListener();
37810
- this.removeClickListener = null;
37811
- }
37812
- }
37813
- get buttonElement() {
37814
- return this.host.getButton();
37815
- }
37816
- isGroupingApplied(group) {
37817
- return isPresent$1(group) && group.length > 0;
37818
- }
37819
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupCommandToolbarDirective, deps: [{ token: i54.ToolBarButtonComponent }, { token: i2.PopupService }, { token: ContextService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: AdaptiveGridService }], target: i0.ɵɵFactoryTarget.Directive });
37820
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupCommandToolbarDirective, isStandalone: true, selector: "[kendoGridGroupTool]", ngImport: i0 });
37821
- }
37822
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupCommandToolbarDirective, decorators: [{
37823
- type: Directive,
37824
- args: [{
37825
- selector: '[kendoGridGroupTool]',
37826
- standalone: true
37827
- }]
37828
- }], ctorParameters: function () { return [{ type: i54.ToolBarButtonComponent }, { type: i2.PopupService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: AdaptiveGridService }]; } });
37829
-
37830
- /**
37831
- * Stores the row and cell highlight state of the Grid.
37832
- *
37833
- * @example
37834
- * ```typescript
37835
- * <kendo-grid kendoGridHighlight="ProductID"></kendo-grid>
37836
- *
37837
- * <kendo-grid [kendoGridHighlight]="myKey"></kendo-grid>
37838
- * ```
37839
- * @remarks
37840
- * Applied to: {@link GridComponent}.
37841
- */
37842
- class HighlightDirective {
37843
- ctx;
37844
- /**
37845
- * Stores the highlighted items keys.
37846
- * @default []
37847
- */
37848
- highlightedKeys = [];
37849
- /**
37850
- * Sets the item key to store in `highlightedKeys`. The Grid uses the row index as the default item key.
37851
- */
37852
- highlightItemKey;
37853
- /**
37854
- * Sets the column key for a data cell. The Grid uses the column index as the default column key.
37855
- */
37856
- highlightColumnKey;
37857
- rowHighlightState = new Set();
37858
- cellHighlightState = new PairSet();
37859
- constructor(ctx) {
37860
- this.ctx = ctx;
37861
- this.ctx.highlightDirective = this;
37862
- }
37863
- ngOnChanges(changes) {
37864
- if (isPresent$1(changes['highlightedKeys'])) {
37865
- this.setState(this.highlightedKeys);
37866
- }
37867
37824
  }
37868
37825
  ngOnDestroy() {
37869
- this.reset();
37870
- this.ctx.highlightDirective = null;
37826
+ super.ngOnDestroy();
37827
+ this.subs.unsubscribe();
37828
+ this.promptOutputs = [];
37871
37829
  }
37872
37830
  /**
37873
37831
  * @hidden
37874
37832
  */
37875
- isRowHighlighted(row) {
37876
- return this.rowHighlightState.has(this.getItemKey(row));
37833
+ onClick() {
37834
+ this.emitOpenClose = true;
37835
+ this.toggleWindow();
37877
37836
  }
37878
37837
  /**
37879
- * @hidden
37838
+ * Toggles the AI Assistant window.
37880
37839
  */
37881
- isCellHighlighted(row, column, colIndex) {
37882
- const highlightItem = this.getHighlightItem(row, column, colIndex);
37883
- return this.cellHighlightState.has(highlightItem.itemKey, highlightItem.columnKey);
37884
- }
37885
- getItemKey(row) {
37886
- if (this.highlightItemKey) {
37887
- if (typeof this.highlightItemKey === "string") {
37888
- return row.data?.[this.highlightItemKey];
37889
- }
37890
- if (typeof this.highlightItemKey === "function") {
37891
- return this.highlightItemKey(row);
37892
- }
37893
- }
37894
- return row.index;
37895
- }
37896
- getHighlightItem(row, col, colIndex) {
37897
- const itemIdentifiers = {};
37898
- itemIdentifiers.itemKey = this.getItemKey(row);
37899
- if (!isPresent$1(col) && !isPresent$1(colIndex)) {
37900
- return itemIdentifiers;
37840
+ toggleWindow() {
37841
+ if (!this.windowRef) {
37842
+ this.openWindow();
37901
37843
  }
37902
- if (this.highlightColumnKey) {
37903
- if (typeof this.highlightColumnKey === "string") {
37904
- itemIdentifiers.columnKey = row.dataItem[this.highlightColumnKey];
37905
- }
37906
- if (typeof this.highlightColumnKey === "function") {
37907
- itemIdentifiers.columnKey = this.highlightColumnKey(col, colIndex);
37908
- }
37844
+ else {
37845
+ this.closeWindow();
37909
37846
  }
37910
- return {
37911
- itemKey: itemIdentifiers.itemKey,
37912
- columnKey: itemIdentifiers.columnKey ? itemIdentifiers.columnKey : colIndex
37913
- };
37914
37847
  }
37915
- setState(highlightedKeys) {
37916
- this.reset();
37917
- if (!highlightedKeys || highlightedKeys.length === 0) {
37918
- return;
37848
+ openWindow() {
37849
+ if (!this.keepOutputHistory) {
37850
+ this.promptOutputs = [];
37919
37851
  }
37920
- const rowHighlights = highlightedKeys.filter(item => !isPresent$1(item.columnKey));
37921
- const cellHighlights = highlightedKeys.filter(item => isPresent$1(item.columnKey));
37922
- if (cellHighlights.length > 0) {
37923
- this.cellHighlightState = new PairSet(cellHighlights, 'itemKey', 'columnKey');
37852
+ const defaultWindowWidth = 437;
37853
+ const rtl = this.ctx.localization.rtl;
37854
+ const defaultWindowSettings = {
37855
+ left: rtl ? this.buttonElement.offsetLeft - (this.aiWindowSettings.width || defaultWindowWidth) : this.buttonElement.offsetLeft + this.buttonElement.offsetWidth,
37856
+ top: this.buttonElement.offsetTop + this.buttonElement.offsetHeight,
37857
+ width: defaultWindowWidth,
37858
+ title: this.ctx.localization.get('aiAssistantWindowTitle'),
37859
+ cssClass: 'k-grid-assistant-window',
37860
+ content: AiAssistantComponent,
37861
+ autoFocusedElement: '.k-input-inner',
37862
+ appendTo: this.ctx.grid.windowContainer
37863
+ };
37864
+ this.aiWindowSettings = {
37865
+ ...defaultWindowSettings,
37866
+ ...this.aiWindowSettings
37867
+ };
37868
+ this.windowRef = this.windowService.open(this.aiWindowSettings);
37869
+ this.windowRef.window.instance.messages = {
37870
+ closeTitle: this.ctx.localization.get('aiAssistantWindowCloseTitle'),
37871
+ maximizeTitle: this.ctx.localization.get('aiAssistantWindowMaximizeTitle'),
37872
+ minimizeTitle: this.ctx.localization.get('aiAssistantWindowMinimizeTitle'),
37873
+ restoreTitle: this.ctx.localization.get('aiAssistantWindowRestoreTitle')
37874
+ };
37875
+ const aiPrompt = this.windowRef.content.instance;
37876
+ aiPrompt.requestUrl = this.requestUrl;
37877
+ aiPrompt.requestOptions = this.requestOptions;
37878
+ aiPrompt.aiToolDirective = this;
37879
+ aiPrompt.disabledGenerateButton = this.aiPromptSettings?.disabledGenerateButton;
37880
+ aiPrompt.streaming = this.aiPromptSettings?.streaming || false;
37881
+ aiPrompt.activeView = this.aiPromptSettings?.activeView || 0;
37882
+ aiPrompt.aiPromptSettings = { ...this.defaultAiPromptSettings, ...this.aiPromptSettings };
37883
+ if (!aiPrompt.aiPromptSettings.promptOutputs) {
37884
+ aiPrompt.aiPromptSettings.promptOutputs = this.promptOutputs;
37924
37885
  }
37925
- if (rowHighlights.length > 0) {
37926
- rowHighlights.forEach(item => {
37927
- this.rowHighlightState.add(item.itemKey);
37886
+ if (this.emitOpenClose) {
37887
+ this.zone.onStable.pipe(take(1)).subscribe(() => {
37888
+ const event = {
37889
+ aiWindow: this.windowRef.window.instance,
37890
+ aiPrompt: this.windowRef.content.instance.aiPrompt
37891
+ };
37892
+ this.open.emit(event);
37893
+ this.emitOpenClose = false;
37928
37894
  });
37929
37895
  }
37896
+ this.subs.add(this.windowRef.window.instance.close.subscribe(() => {
37897
+ this.emitOpenClose = true;
37898
+ this.closeWindow(true);
37899
+ }));
37900
+ this.host.selected = true;
37930
37901
  }
37931
- reset() {
37932
- this.rowHighlightState.clear();
37933
- this.cellHighlightState.clear();
37902
+ closeWindow(focusAnchor = false) {
37903
+ this.windowRef.close();
37904
+ if (this.emitOpenClose) {
37905
+ this.close.emit();
37906
+ this.emitOpenClose = false;
37907
+ }
37908
+ this.windowRef = null;
37909
+ this.buttonElement?.setAttribute('aria-expanded', 'false');
37910
+ this.buttonElement?.removeAttribute('aria-controls');
37911
+ this.host.selected = false;
37912
+ focusAnchor && this.buttonElement?.focus();
37934
37913
  }
37935
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HighlightDirective, deps: [{ token: ContextService }], target: i0.ɵɵFactoryTarget.Directive });
37936
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: HighlightDirective, isStandalone: true, selector: "[kendoGridHighlight]", inputs: { highlightedKeys: "highlightedKeys", highlightItemKey: ["kendoGridHighlight", "highlightItemKey"], highlightColumnKey: "highlightColumnKey" }, usesOnChanges: true, ngImport: i0 });
37914
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIAssistantToolbarDirective, deps: [{ token: i1$7.WindowService }, { token: i54.ToolBarButtonComponent }, { token: ContextService }, { token: i0.NgZone }, { token: i54.RefreshService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
37915
+ 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 });
37937
37916
  }
37938
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HighlightDirective, decorators: [{
37917
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIAssistantToolbarDirective, decorators: [{
37939
37918
  type: Directive,
37940
37919
  args: [{
37941
- selector: '[kendoGridHighlight]',
37920
+ selector: '[kendoGridAIAssistantTool]',
37942
37921
  standalone: true
37943
37922
  }]
37944
- }], ctorParameters: function () { return [{ type: ContextService }]; }, propDecorators: { highlightedKeys: [{
37923
+ }], ctorParameters: function () { return [{ type: i1$7.WindowService }, { type: i54.ToolBarButtonComponent }, { type: ContextService }, { type: i0.NgZone }, { type: i54.RefreshService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { requestUrl: [{
37945
37924
  type: Input
37946
- }], highlightItemKey: [{
37947
- type: Input,
37948
- args: ["kendoGridHighlight"]
37949
- }], highlightColumnKey: [{
37925
+ }], requestOptions: [{
37926
+ type: Input
37927
+ }], aiWindowSettings: [{
37928
+ type: Input
37929
+ }], aiPromptSettings: [{
37950
37930
  type: Input
37931
+ }], autoClose: [{
37932
+ type: Input
37933
+ }], keepOutputHistory: [{
37934
+ type: Input
37935
+ }], promptRequest: [{
37936
+ type: Output
37937
+ }], cancelRequest: [{
37938
+ type: Output
37939
+ }], responseSuccess: [{
37940
+ type: Output
37941
+ }], responseError: [{
37942
+ type: Output
37943
+ }], close: [{
37944
+ type: Output
37945
+ }], open: [{
37946
+ type: Output
37951
37947
  }] } });
37952
37948
 
37953
37949
  /**