@progress/kendo-angular-grid 20.1.0-develop.3 → 20.1.0-develop.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/column-menu/column-list.component.d.ts +0 -2
  2. package/columns/column.component.d.ts +8 -1
  3. package/columns/command-column.component.d.ts +1 -1
  4. package/columns/span-column.component.d.ts +1 -1
  5. package/editing/cancel-command.directive.d.ts +1 -1
  6. package/editing/edit-row-options.interface.d.ts +1 -1
  7. package/editing/edit-template.directive.d.ts +1 -1
  8. package/editing/remove-command.directive.d.ts +1 -1
  9. package/editing/save-command.directive.d.ts +1 -1
  10. package/editing-directives/edit-service.interface.d.ts +2 -2
  11. package/editing-directives/external-editing.directive.d.ts +1 -1
  12. package/editing-directives/in-cell-editing.directive.d.ts +1 -1
  13. package/editing-directives/reactive-editing.directive.d.ts +1 -1
  14. package/editing-directives/template-editing.directive.d.ts +1 -1
  15. package/esm2022/column-menu/column-list-kb-nav.service.mjs +1 -1
  16. package/esm2022/column-menu/column-list.component.mjs +7 -43
  17. package/esm2022/column-menu/column-menu-container.component.mjs +10 -1
  18. package/esm2022/column-menu/column-menu.component.mjs +7 -1
  19. package/esm2022/columns/column.component.mjs +9 -1
  20. package/esm2022/columns/command-column.component.mjs +1 -1
  21. package/esm2022/columns/span-column.component.mjs +1 -1
  22. package/esm2022/common/clipboard.directive.mjs +3 -0
  23. package/esm2022/editing/cancel-command.directive.mjs +1 -1
  24. package/esm2022/editing/edit-template.directive.mjs +1 -1
  25. package/esm2022/editing/remove-command.directive.mjs +1 -1
  26. package/esm2022/editing/save-command.directive.mjs +1 -1
  27. package/esm2022/editing-directives/external-editing.directive.mjs +1 -1
  28. package/esm2022/editing-directives/in-cell-editing.directive.mjs +1 -1
  29. package/esm2022/editing-directives/reactive-editing.directive.mjs +1 -1
  30. package/esm2022/editing-directives/template-editing.directive.mjs +1 -1
  31. package/esm2022/filtering/menu/filter-menu-container.component.mjs +120 -31
  32. package/esm2022/filtering/menu/filter-menu-input-wrapper.component.mjs +2 -2
  33. package/esm2022/filtering/menu/filter-menu.component.mjs +11 -7
  34. package/esm2022/filtering/multicheckbox-filter.component.mjs +290 -0
  35. package/esm2022/grid.component.mjs +25 -12
  36. package/esm2022/index.mjs +1 -0
  37. package/esm2022/localization/messages.mjs +28 -1
  38. package/esm2022/navigation/logical-cell.directive.mjs +8 -2
  39. package/esm2022/navigation/navigation.service.mjs +1 -0
  40. package/esm2022/package-metadata.mjs +2 -2
  41. package/esm2022/pdf/pdf.component.mjs +8 -3
  42. package/esm2022/rendering/cell.component.mjs +2 -2
  43. package/esm2022/rendering/common/field-accessor.pipe.mjs +1 -1
  44. package/esm2022/rendering/common/format.pipe.mjs +37 -0
  45. package/esm2022/rendering/header/header.component.mjs +1 -1
  46. package/esm2022/rendering/list.component.mjs +2 -2
  47. package/esm2022/rendering/table-body.component.mjs +4 -2
  48. package/esm2022/rendering/toolbar/tools/column-chooser-tool.directive.mjs +1 -1
  49. package/esm2022/rendering/toolbar/tools/filter-toolbar-tool.component.mjs +1 -1
  50. package/esm2022/rendering/toolbar/tools/group-toolbar-tool.component.mjs +2 -2
  51. package/esm2022/rendering/toolbar/tools/sort-toolbar-tool.component.mjs +1 -1
  52. package/esm2022/scrolling/scroller.service.mjs +0 -3
  53. package/fesm2022/progress-kendo-angular-grid.mjs +1781 -1348
  54. package/filtering/filterable.d.ts +23 -0
  55. package/filtering/menu/filter-menu-container.component.d.ts +5 -1
  56. package/filtering/menu/filter-menu.component.d.ts +3 -4
  57. package/filtering/multicheckbox-filter.component.d.ts +43 -0
  58. package/grid.component.d.ts +4 -6
  59. package/index.d.ts +1 -0
  60. package/localization/messages.d.ts +22 -1
  61. package/navigation/navigation.service.d.ts +1 -0
  62. package/package.json +21 -21
  63. package/rendering/common/format.pipe.d.ts +17 -0
  64. package/schematics/ngAdd/index.js +4 -4
@@ -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, 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';
@@ -32,7 +32,7 @@ import { NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule, FormControl, FormG
32
32
  import * as i2$1 from '@progress/kendo-angular-utils';
33
33
  import { DragTargetContainerDirective, DropTargetContainerDirective } from '@progress/kendo-angular-utils';
34
34
  import * as i4 from '@progress/kendo-angular-inputs';
35
- import { TextBoxComponent, NumericTextBoxComponent, NumericTextBoxCustomMessagesComponent, RadioButtonComponent, CheckBoxComponent, KENDO_FORMFIELD, KENDO_TEXTBOX, KENDO_NUMERICTEXTBOX, KENDO_CHECKBOX } from '@progress/kendo-angular-inputs';
35
+ import { TextBoxComponent, NumericTextBoxComponent, NumericTextBoxCustomMessagesComponent, RadioButtonComponent, CheckBoxComponent, TextBoxPrefixTemplateDirective, KENDO_FORMFIELD, KENDO_TEXTBOX, KENDO_NUMERICTEXTBOX, KENDO_CHECKBOX } from '@progress/kendo-angular-inputs';
36
36
  import * as i5 from '@progress/kendo-angular-dateinputs';
37
37
  import { DatePickerComponent, DatePickerCustomMessagesComponent, KENDO_DATEPICKER, CalendarDOMService, CenturyViewService, DecadeViewService, MonthViewService, YearViewService, NavigationService as NavigationService$1 } from '@progress/kendo-angular-dateinputs';
38
38
  import * as i54 from '@progress/kendo-angular-toolbar';
@@ -1933,7 +1933,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1933
1933
  }] }]; } });
1934
1934
 
1935
1935
  /**
1936
- * Lets you customize the content of edited cells by providing a column edit-cell template for the Grid ([see example](slug:custom_reactive_editing_grid#toc-setting-up-custom-inputs)).
1936
+ * Lets you customize the content of edited cells by providing a column edit-cell template for the Grid ([see example](slug:custom_editors_grid#setting-up-custom-editors)).
1937
1937
  * Place an `<ng-template>` tag with the `kendoGridEditTemplate` directive inside a `<kendo-grid-column>` tag to define the template.
1938
1938
  *
1939
1939
  * The template context includes:
@@ -2869,6 +2869,12 @@ class ColumnComponent extends ColumnBase {
2869
2869
  * @default 'text'
2870
2870
  */
2871
2871
  filter = 'text';
2872
+ /**
2873
+ * Specifies the filter type for the filter menu UI.
2874
+ *
2875
+ * @default 'default'
2876
+ */
2877
+ filterVariant = 'default';
2872
2878
  /**
2873
2879
  * Shows or hides the filter UI for this column. [See example](slug:filtering_grid).
2874
2880
  *
@@ -2916,7 +2922,7 @@ class ColumnComponent extends ColumnBase {
2916
2922
  return this.title === undefined ? this.field : this.title;
2917
2923
  }
2918
2924
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnComponent, deps: [{ token: ColumnBase, host: true, optional: true, skipSelf: true }, { token: IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
2919
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnComponent, isStandalone: true, selector: "kendo-grid-column", inputs: { field: "field", format: "format", sortable: "sortable", groupable: "groupable", editor: "editor", filter: "filter", filterable: "filterable", editable: "editable" }, providers: [
2925
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnComponent, isStandalone: true, selector: "kendo-grid-column", inputs: { field: "field", format: "format", sortable: "sortable", groupable: "groupable", editor: "editor", filter: "filter", filterVariant: "filterVariant", filterable: "filterable", editable: "editable" }, providers: [
2920
2926
  {
2921
2927
  provide: ColumnBase,
2922
2928
  useExisting: forwardRef(() => ColumnComponent)
@@ -2956,6 +2962,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2956
2962
  type: Input
2957
2963
  }], filter: [{
2958
2964
  type: Input
2965
+ }], filterVariant: [{
2966
+ type: Input
2959
2967
  }], filterable: [{
2960
2968
  type: Input
2961
2969
  }], editable: [{
@@ -3045,7 +3053,7 @@ class SpanColumnComponent extends ColumnBase {
3045
3053
  includeInChooser = false;
3046
3054
  /**
3047
3055
  * Sets whether the edit template of the column is rendered.
3048
- * To enable editing for a spanned column, set an edit template for it ([see example](slug:custom_reactive_editing_grid)).
3056
+ * To enable editing for a spanned column, set an edit template for it ([see example](slug:custom_editors_grid#setting-up-custom-editors)).
3049
3057
  * @default false
3050
3058
  */
3051
3059
  set editable(value) {
@@ -3507,6 +3515,7 @@ class NavigationService {
3507
3515
  return columnIndexInsideGroup !== columnGroupChildren.length - 1;
3508
3516
  }
3509
3517
  }
3518
+ preventScroll = false;
3510
3519
  viewport;
3511
3520
  columnViewport;
3512
3521
  activeRowIndex = 0;
@@ -5264,8 +5273,14 @@ class LogicalCellDirective {
5264
5273
  this.focusGroup.focus();
5265
5274
  }
5266
5275
  else {
5267
- if (!this.logicalSlaveCell && this.navigationService.autoFocusCell(this.logicalColIndex, this.logicalColIndex + this.colSpan - 1)) {
5268
- this.microtask(() => this.isFocused() && el.focus());
5276
+ if (!this.logicalSlaveCell &&
5277
+ this.navigationService.autoFocusCell(this.logicalColIndex, this.logicalColIndex + this.colSpan - 1)) {
5278
+ this.microtask(() => {
5279
+ if (this.isFocused()) {
5280
+ el.focus({ preventScroll: this.navigationService.preventScroll });
5281
+ this.navigationService.preventScroll = false;
5282
+ }
5283
+ });
5269
5284
  }
5270
5285
  this.renderer.addClass(el, 'k-focus');
5271
5286
  }
@@ -5478,7 +5493,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
5478
5493
  args: ['attr.aria-owns']
5479
5494
  }] } });
5480
5495
 
5481
- const FORMAT_REGEX = /\{\d+:?/;
5496
+ const FORMAT_REGEX$1 = /\{\d+:?/;
5482
5497
  /**
5483
5498
  * @hidden
5484
5499
  */
@@ -5499,7 +5514,7 @@ class FieldAccessorPipe {
5499
5514
  }
5500
5515
  formatValue(format, value) {
5501
5516
  const intl = this.intlService;
5502
- if (isString(format) && format.match(FORMAT_REGEX)) {
5517
+ if (isString(format) && FORMAT_REGEX$1.exec(format)) {
5503
5518
  return intl.format(format, value);
5504
5519
  }
5505
5520
  return intl.toString(value, format);
@@ -8964,11 +8979,11 @@ class FilterMenuInputWrapperComponent extends FilterInputWrapperComponent {
8964
8979
  this.filterService.menuTabbingService.firstFocusable = this.firstOperatorDropDown;
8965
8980
  if (this.ctx.grid?.isActionSheetExpanded) {
8966
8981
  this.subs.add(this.adaptiveGridService.animationEnd.subscribe(() => {
8967
- this.firstOperatorDropDown.focus();
8982
+ this.firstOperatorDropDown.wrapper.nativeElement.focus({ preventScroll: true });
8968
8983
  }));
8969
8984
  }
8970
8985
  else {
8971
- this.firstOperatorDropDown.focus();
8986
+ this.firstOperatorDropDown.wrapper.nativeElement.focus({ preventScroll: true });
8972
8987
  }
8973
8988
  }
8974
8989
  }
@@ -10670,6 +10685,322 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
10670
10685
  type: Input
10671
10686
  }] } });
10672
10687
 
10688
+ /**
10689
+ * @hidden
10690
+ */
10691
+ class LocalDataChangesService {
10692
+ changes = new EventEmitter();
10693
+ data;
10694
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalDataChangesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
10695
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalDataChangesService });
10696
+ }
10697
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalDataChangesService, decorators: [{
10698
+ type: Injectable
10699
+ }] });
10700
+
10701
+ const FORMAT_REGEX = /\{\d+:?/;
10702
+ /**
10703
+ * @hidden
10704
+ */
10705
+ class FormatPipe {
10706
+ intlService;
10707
+ constructor(intlService) {
10708
+ this.intlService = intlService;
10709
+ }
10710
+ transform(value, format) {
10711
+ const intl = this.intlService;
10712
+ if (isString(format) && FORMAT_REGEX.exec(format)) {
10713
+ return intl.format(format, value);
10714
+ }
10715
+ return intl.toString(value, format);
10716
+ }
10717
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FormatPipe, deps: [{ token: i1$4.IntlService }], target: i0.ɵɵFactoryTarget.Pipe });
10718
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: FormatPipe, isStandalone: true, name: "format", pure: false });
10719
+ }
10720
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FormatPipe, decorators: [{
10721
+ type: Pipe,
10722
+ args: [{
10723
+ // eslint-disable-next-line @angular-eslint/pipe-prefix
10724
+ name: 'format',
10725
+ pure: false,
10726
+ standalone: true
10727
+ }]
10728
+ }], ctorParameters: function () { return [{ type: i1$4.IntlService }]; } });
10729
+
10730
+ const DEFAULT_SEARCH_DELAY = 500;
10731
+ /**
10732
+ * @hidden
10733
+ */
10734
+ class MultiCheckboxFilterComponent {
10735
+ ctx;
10736
+ dataChangesService;
10737
+ column;
10738
+ filterChange = new EventEmitter();
10739
+ constructor(ctx, dataChangesService) {
10740
+ this.ctx = ctx;
10741
+ this.dataChangesService = dataChangesService;
10742
+ }
10743
+ listData;
10744
+ searchIcon = searchIcon;
10745
+ showSelectAll = true;
10746
+ currentlySelected = new Set();
10747
+ isSearched = false;
10748
+ currentFilter;
10749
+ typingTimeout;
10750
+ baseListData;
10751
+ ngOnInit() {
10752
+ let mappedData = [];
10753
+ let filteredMappedData = [];
10754
+ if (this.column.filter === 'date') {
10755
+ mappedData = this.getUniqueDateValues(this.gridData);
10756
+ filteredMappedData = this.getUniqueDateValues(this.filteredGridData);
10757
+ this.baseListData = mappedData.sort((a, b) => { return a - b; });
10758
+ this.currentlySelected = new Set(filteredMappedData);
10759
+ }
10760
+ else {
10761
+ mappedData = this.gridData.map(i => i[this.column.field]);
10762
+ filteredMappedData = this.filteredGridData.map(i => i[this.column.field]);
10763
+ this.baseListData = [...new Set(mappedData)].sort((a, b) => { return a - b; });
10764
+ this.currentlySelected = new Set(filteredMappedData);
10765
+ }
10766
+ this.listData = this.baseListData;
10767
+ this.currentFilter = this.ctx.grid?.filter;
10768
+ if (this.currentFilter) {
10769
+ this.filterChange.emit(this.currentFilter);
10770
+ }
10771
+ }
10772
+ ngOnDestroy() {
10773
+ if (this.typingTimeout) {
10774
+ clearTimeout(this.typingTimeout);
10775
+ this.typingTimeout = null;
10776
+ }
10777
+ }
10778
+ isItemSelected(item) {
10779
+ return this.currentlySelected.has(item);
10780
+ }
10781
+ onSearch(value) {
10782
+ clearTimeout(this.typingTimeout);
10783
+ this.typingTimeout = setTimeout(() => {
10784
+ this.isSearched = value.length > 0;
10785
+ this.showSelectAll = !this.isSearched;
10786
+ const field = this.column?.field;
10787
+ if (!field) {
10788
+ this.listData = [];
10789
+ return;
10790
+ }
10791
+ if (!value) {
10792
+ this.listData = this.baseListData;
10793
+ return;
10794
+ }
10795
+ this.listData = filterBy(this.baseListData, { operator: 'contains', value });
10796
+ }, DEFAULT_SEARCH_DELAY);
10797
+ }
10798
+ handleCheckBoxChange(checkedState, value, selectAllChecked) {
10799
+ const field = this.column?.field;
10800
+ if (!field) {
10801
+ return;
10802
+ }
10803
+ if (!this.currentFilter) {
10804
+ const existing = this.ctx.grid.filter;
10805
+ this.currentFilter = existing ? { ...existing } : { logic: 'and', filters: [] };
10806
+ }
10807
+ const compositeIndex = this.currentFilter.filters.findIndex((f) => f && Array.isArray(f.filters) && f.filters.some((ff) => ff.field === field));
10808
+ let fieldFilters = [];
10809
+ if (compositeIndex !== -1) {
10810
+ fieldFilters = [...this.currentFilter.filters[compositeIndex].filters];
10811
+ }
10812
+ const valueForItem = (item) => item?.[field];
10813
+ if (selectAllChecked) {
10814
+ if (checkedState) {
10815
+ fieldFilters = [];
10816
+ this.currentlySelected = new Set(this.baseListData);
10817
+ }
10818
+ else {
10819
+ fieldFilters = this.gridData.map(item => ({
10820
+ field,
10821
+ operator: 'neq',
10822
+ value: valueForItem(item)
10823
+ }));
10824
+ this.currentlySelected.clear();
10825
+ }
10826
+ }
10827
+ else {
10828
+ const exists = fieldFilters.some(f => f.value === value);
10829
+ if (checkedState) {
10830
+ if (!exists) {
10831
+ fieldFilters.push({ field, operator: 'eq', value });
10832
+ }
10833
+ else {
10834
+ fieldFilters = fieldFilters.filter(f => f.value !== value);
10835
+ }
10836
+ this.currentlySelected.add(value);
10837
+ }
10838
+ else {
10839
+ if (exists) {
10840
+ fieldFilters = fieldFilters.filter(f => f.value !== value);
10841
+ }
10842
+ else {
10843
+ fieldFilters.push({ field, operator: 'neq', value });
10844
+ }
10845
+ this.currentlySelected.delete(value);
10846
+ }
10847
+ }
10848
+ if (fieldFilters.length === 0) {
10849
+ if (compositeIndex !== -1) {
10850
+ this.currentFilter.filters.splice(compositeIndex, 1);
10851
+ }
10852
+ else {
10853
+ this.currentFilter.filters = fieldFilters;
10854
+ }
10855
+ }
10856
+ else {
10857
+ const compositeBlock = {
10858
+ logic: 'and',
10859
+ filters: fieldFilters
10860
+ };
10861
+ if (compositeIndex !== -1) {
10862
+ this.currentFilter.filters[compositeIndex] = compositeBlock;
10863
+ }
10864
+ else {
10865
+ this.currentFilter.filters.push(compositeBlock);
10866
+ }
10867
+ }
10868
+ this.filterChange.emit(this.currentFilter);
10869
+ }
10870
+ get filteredGridData() {
10871
+ return filterBy(this.gridData, this.ctx.grid?.filter);
10872
+ }
10873
+ get selectAllChecked() {
10874
+ if (!this.listData) {
10875
+ return false;
10876
+ }
10877
+ if (this.currentlySelected.size >= this.listData.length && this.currentlySelected.size > 0) {
10878
+ return true;
10879
+ }
10880
+ else if (this.currentlySelected.size === 0) {
10881
+ return false;
10882
+ }
10883
+ else {
10884
+ return 'indeterminate';
10885
+ }
10886
+ }
10887
+ get gridData() {
10888
+ let data = [];
10889
+ const isLocalData = isPresent$1(this.ctx?.dataBindingDirective);
10890
+ if (isPresent$1(this.normalizedFilterVariant.data)) {
10891
+ data = this.normalizedFilterVariant.data;
10892
+ }
10893
+ else if (isLocalData) {
10894
+ data = this.dataChangesService.data;
10895
+ }
10896
+ else {
10897
+ data = this.ctx.grid?.flatData;
10898
+ }
10899
+ return data || [];
10900
+ }
10901
+ get normalizedFilterVariant() {
10902
+ const defaultMultiCheckboxSettings = { variant: 'multiCheckbox', search: true };
10903
+ if (typeof this.column?.filterVariant === 'string') {
10904
+ return {
10905
+ variant: this.column.filterVariant,
10906
+ search: true
10907
+ };
10908
+ }
10909
+ return Object.assign(defaultMultiCheckboxSettings, this.column?.filterVariant);
10910
+ }
10911
+ get selectedItemsMessage() {
10912
+ const localizationMsg = this.messageFor('multiCheckboxFilterSelectedItemsCount') || '';
10913
+ return replaceMessagePlaceholder(localizationMsg, 'selectedItemsCount', this.currentlySelected.size.toString());
10914
+ }
10915
+ messageFor(key) {
10916
+ return this.ctx.localization.get(key);
10917
+ }
10918
+ getUniqueDateValues(data) {
10919
+ return data.reduce((acc, current) => {
10920
+ const value = current[this.column.field];
10921
+ if (value instanceof Date && acc.findIndex(d => d.getTime() === value.getTime()) === -1) {
10922
+ acc.push(value);
10923
+ }
10924
+ return acc;
10925
+ }, []);
10926
+ }
10927
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MultiCheckboxFilterComponent, deps: [{ token: ContextService }, { token: LocalDataChangesService }], target: i0.ɵɵFactoryTarget.Component });
10928
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: MultiCheckboxFilterComponent, isStandalone: true, selector: "kendo-grid-multicheckbox-filter", inputs: { column: "column" }, outputs: { filterChange: "filterChange" }, ngImport: i0, template: `
10929
+ <kendo-textbox *ngIf="normalizedFilterVariant.search"
10930
+ class="k-searchbox"
10931
+ [placeholder]="messageFor('multiCheckboxFilterSearchPlaceholder')"
10932
+ (valueChange)="onSearch($event)">
10933
+ <ng-template kendoTextBoxPrefixTemplate>
10934
+ <kendo-icon-wrapper innerCssClass="k-input-icon" name="search" [svgIcon]="searchIcon"></kendo-icon-wrapper>
10935
+ </ng-template>
10936
+ </kendo-textbox>
10937
+ <ul class="k-reset k-multicheck-wrap">
10938
+ <li class="k-item k-check-all-wrap" *ngIf="showSelectAll">
10939
+ <label class="k-label k-checkbox-label" role="option">
10940
+ <kendo-checkbox
10941
+ [checkedState]="selectAllChecked"
10942
+ (checkedStateChange)="handleCheckBoxChange($event, null, true)">
10943
+ </kendo-checkbox>
10944
+ <span>{{ messageFor('multiCheckboxFilterSelectAllLabel') }}</span>
10945
+ </label>
10946
+ </li>
10947
+ <li class="k-item" *ngFor="let item of listData">
10948
+ <label class="k-label k-checkbox-label" role="option">
10949
+ <kendo-checkbox
10950
+ [checkedState]="isItemSelected(item)"
10951
+ (checkedStateChange)="handleCheckBoxChange($event, item)">
10952
+ </kendo-checkbox>
10953
+ <span>{{ item | format: column.format }}</span>
10954
+ </label>
10955
+ </li>
10956
+ </ul>
10957
+ <div class="k-filter-selected-items">{{selectedItemsMessage}}</div>
10958
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CheckBoxComponent, selector: "kendo-checkbox", inputs: ["checkedState", "rounded"], outputs: ["checkedStateChange"], exportAs: ["kendoCheckBox"] }, { kind: "component", type: TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "directive", type: TextBoxPrefixTemplateDirective, selector: "[kendoTextBoxPrefixTemplate]", inputs: ["showSeparator"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "pipe", type: FormatPipe, name: "format" }] });
10959
+ }
10960
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MultiCheckboxFilterComponent, decorators: [{
10961
+ type: Component,
10962
+ args: [{
10963
+ selector: 'kendo-grid-multicheckbox-filter',
10964
+ template: `
10965
+ <kendo-textbox *ngIf="normalizedFilterVariant.search"
10966
+ class="k-searchbox"
10967
+ [placeholder]="messageFor('multiCheckboxFilterSearchPlaceholder')"
10968
+ (valueChange)="onSearch($event)">
10969
+ <ng-template kendoTextBoxPrefixTemplate>
10970
+ <kendo-icon-wrapper innerCssClass="k-input-icon" name="search" [svgIcon]="searchIcon"></kendo-icon-wrapper>
10971
+ </ng-template>
10972
+ </kendo-textbox>
10973
+ <ul class="k-reset k-multicheck-wrap">
10974
+ <li class="k-item k-check-all-wrap" *ngIf="showSelectAll">
10975
+ <label class="k-label k-checkbox-label" role="option">
10976
+ <kendo-checkbox
10977
+ [checkedState]="selectAllChecked"
10978
+ (checkedStateChange)="handleCheckBoxChange($event, null, true)">
10979
+ </kendo-checkbox>
10980
+ <span>{{ messageFor('multiCheckboxFilterSelectAllLabel') }}</span>
10981
+ </label>
10982
+ </li>
10983
+ <li class="k-item" *ngFor="let item of listData">
10984
+ <label class="k-label k-checkbox-label" role="option">
10985
+ <kendo-checkbox
10986
+ [checkedState]="isItemSelected(item)"
10987
+ (checkedStateChange)="handleCheckBoxChange($event, item)">
10988
+ </kendo-checkbox>
10989
+ <span>{{ item | format: column.format }}</span>
10990
+ </label>
10991
+ </li>
10992
+ </ul>
10993
+ <div class="k-filter-selected-items">{{selectedItemsMessage}}</div>
10994
+ `,
10995
+ standalone: true,
10996
+ imports: [NgFor, NgIf, CheckBoxComponent, TextBoxComponent, TextBoxPrefixTemplateDirective, IconWrapperComponent, FormatPipe]
10997
+ }]
10998
+ }], ctorParameters: function () { return [{ type: ContextService }, { type: LocalDataChangesService }]; }, propDecorators: { column: [{
10999
+ type: Input
11000
+ }], filterChange: [{
11001
+ type: Output
11002
+ }] } });
11003
+
10673
11004
  const isNoValueOperator = operator => (operator === "isnull"
10674
11005
  || operator === "isnotnull"
10675
11006
  || operator === "isempty"
@@ -10754,11 +11085,11 @@ class FilterMenuContainerComponent {
10754
11085
  return this._childFilter;
10755
11086
  }
10756
11087
  resetButton;
10757
- filterButton;
10758
11088
  _childFilter;
10759
11089
  subscription;
10760
11090
  _templateContext = {};
10761
11091
  _filter;
11092
+ checkboxFilter;
10762
11093
  constructor(parentService, childService, ctx, cd, menuTabbingService, adaptiveGridService) {
10763
11094
  this.parentService = parentService;
10764
11095
  this.childService = childService;
@@ -10784,7 +11115,7 @@ class FilterMenuContainerComponent {
10784
11115
  this.menuTabbingService.lastFocusable = undefined;
10785
11116
  }
10786
11117
  get disabled() {
10787
- return !this.childFilter.filters.some(validFilters);
11118
+ return this.isMultiFilter ? this.areFiltersEqual : !this.childFilter.filters.some(validFilters);
10788
11119
  }
10789
11120
  get templateContext() {
10790
11121
  this._templateContext.column = this.column;
@@ -10797,15 +11128,20 @@ class FilterMenuContainerComponent {
10797
11128
  return isPresent(this.column) && isPresent(this.column.filterMenuTemplateRef);
10798
11129
  }
10799
11130
  submit() {
10800
- const filter = trimFilters(this.childFilter);
10801
- if (filter.filters.length) {
10802
- const root = this.filter || {
10803
- filters: [],
10804
- logic: "and"
10805
- };
10806
- removeFilter(root, this.column.field);
10807
- root.filters.push(filter);
10808
- this.parentService.filter(root);
11131
+ if (this.isMultiFilter) {
11132
+ this.parentService.filter(this.checkboxFilter);
11133
+ }
11134
+ else {
11135
+ const filter = trimFilters(this.childFilter);
11136
+ if (filter.filters.length) {
11137
+ const root = this.filter || {
11138
+ filters: [],
11139
+ logic: "and"
11140
+ };
11141
+ removeFilter(root, this.column.field);
11142
+ root.filters.push(filter);
11143
+ this.parentService.filter(root);
11144
+ }
10809
11145
  }
10810
11146
  this.close.emit();
10811
11147
  return false;
@@ -10833,29 +11169,100 @@ class FilterMenuContainerComponent {
10833
11169
  }
10834
11170
  }
10835
11171
  }
11172
+ onCheckboxFilterChange(filter) {
11173
+ this.checkboxFilter = filter;
11174
+ }
11175
+ getButtonIcon(buttonType, iconType) {
11176
+ if (!this.isMultiFilter) {
11177
+ return;
11178
+ }
11179
+ const icons = {
11180
+ filter: {
11181
+ icon: 'filter',
11182
+ svgIcon: filterIcon
11183
+ },
11184
+ reset: {
11185
+ icon: 'filter-clear',
11186
+ svgIcon: filterClearIcon
11187
+ }
11188
+ };
11189
+ return icons[buttonType]?.[iconType];
11190
+ }
10836
11191
  get clearText() {
10837
11192
  return this.ctx.localization.get("filterClearButton");
10838
11193
  }
10839
11194
  get filterText() {
10840
11195
  return this.ctx.localization.get("filterFilterButton");
10841
11196
  }
11197
+ get isMultiFilter() {
11198
+ if (!isPresent(this.column?.filterVariant)) {
11199
+ return false;
11200
+ }
11201
+ const filterVariant = this.column?.filterVariant;
11202
+ return isPresent(filterVariant) && (filterVariant === 'multiCheckbox' || typeof filterVariant === 'object' && filterVariant.variant === 'multiCheckbox');
11203
+ }
11204
+ get areFiltersEqual() {
11205
+ const checkboxFilter = this.checkboxFilter;
11206
+ const gridFilter = this.filter;
11207
+ const isComposite = (f) => !!f && Array.isArray(f.filters);
11208
+ // Treat undefined and "empty (no inner filters)" as equivalent
11209
+ const isEmptyComposite = (f) => isComposite(f) && f.filters.length === 0;
11210
+ if (!checkboxFilter && !gridFilter) {
11211
+ return true;
11212
+ }
11213
+ if ((!checkboxFilter && isEmptyComposite(gridFilter)) || (!gridFilter && isEmptyComposite(checkboxFilter))) {
11214
+ return true;
11215
+ }
11216
+ if (!checkboxFilter || !gridFilter) {
11217
+ return false;
11218
+ }
11219
+ const eq = (x, y) => {
11220
+ const xIsComp = isComposite(x);
11221
+ const yIsComp = isComposite(y);
11222
+ if (xIsComp !== yIsComp) {
11223
+ return false;
11224
+ }
11225
+ if (xIsComp) {
11226
+ const xLogic = x.logic || 'and';
11227
+ const yLogic = y.logic || 'and';
11228
+ if (xLogic !== yLogic) {
11229
+ return false;
11230
+ }
11231
+ if (x.filters.length !== y.filters.length) {
11232
+ return false;
11233
+ }
11234
+ for (let i = 0; i < x.filters.length; i++) {
11235
+ if (!eq(x.filters[i], y.filters[i])) {
11236
+ return false;
11237
+ }
11238
+ }
11239
+ return true;
11240
+ }
11241
+ return areObjectsEqual(x, y);
11242
+ };
11243
+ return eq(checkboxFilter, gridFilter);
11244
+ }
10842
11245
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterMenuContainerComponent, deps: [{ token: FilterService, skipSelf: true }, { token: FilterService }, { token: ContextService }, { token: i0.ChangeDetectorRef }, { token: MenuTabbingService }, { token: AdaptiveGridService }], target: i0.ɵɵFactoryTarget.Component });
10843
11246
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FilterMenuContainerComponent, isStandalone: true, selector: "kendo-grid-filter-menu-container", inputs: { column: "column", isLast: "isLast", isExpanded: "isExpanded", menuTabbingService: "menuTabbingService", filter: "filter", actionsClass: "actionsClass" }, outputs: { close: "close" }, providers: [
10844
11247
  FilterService,
10845
11248
  MenuTabbingService
10846
- ], viewQueries: [{ propertyName: "resetButton", first: true, predicate: ["resetButton"], descendants: true }, { propertyName: "filterButton", first: true, predicate: ["filterButton"], descendants: true }], ngImport: i0, template: `
11249
+ ], viewQueries: [{ propertyName: "resetButton", first: true, predicate: ["resetButton"], descendants: true }], ngImport: i0, template: `
10847
11250
  <form (submit)="submit()" (reset)="reset()"
10848
- class="k-filter-menu">
11251
+ class="k-filter-menu"
11252
+ [ngClass]="{'k-popup k-group k-reset': isMultiFilter && !ctx.grid?.isActionSheetExpanded}">
10849
11253
  <div class="k-filter-menu-container">
10850
11254
  <ng-container [ngSwitch]="hasTemplate">
10851
11255
  <ng-container *ngSwitchCase="false">
10852
- <ng-container
11256
+ <ng-container *ngIf="!isMultiFilter; else multiFilter"
10853
11257
  kendoFilterMenuHost
10854
11258
  [filterService]="childService"
10855
11259
  [column]="column"
10856
11260
  [filter]="childFilter"
10857
11261
  [menuTabbingService]="menuTabbingService">
10858
11262
  </ng-container>
11263
+ <ng-template #multiFilter>
11264
+ <kendo-grid-multicheckbox-filter [column]="column" (filterChange)="onCheckboxFilterChange($event)"></kendo-grid-multicheckbox-filter>
11265
+ </ng-template>
10859
11266
  </ng-container>
10860
11267
  <ng-container *ngSwitchCase="true">
10861
11268
  <ng-template
@@ -10867,20 +11274,24 @@ class FilterMenuContainerComponent {
10867
11274
  </ng-container>
10868
11275
  </ng-container>
10869
11276
  <div *ngIf="!ctx.grid?.isActionSheetExpanded" [ngClass]="actionsClass">
10870
- <button #filterButton
11277
+ <button #filterButton kendoButton
11278
+ themeColor="primary"
10871
11279
  type="submit"
10872
- class="k-button k-button-solid-primary k-button-solid k-button-md k-rounded-md k-button-rectangle"
11280
+ [ngClass]="{'k-button-rectangle': !isMultiFilter}"
10873
11281
  [disabled]="disabled"
11282
+ [icon]="getButtonIcon('filter', 'icon')"
11283
+ [svgIcon]="getButtonIcon('filter', 'svgIcon')"
10874
11284
  (keydown.tab)="onTab($event, 'filter')">{{filterText}}</button>
10875
- <button
10876
- #resetButton
11285
+ <button #resetButton kendoButton
10877
11286
  type="reset"
10878
- class="k-button k-button-solid-base k-button-solid k-button-md k-rounded-md k-button-rectangle"
11287
+ [ngClass]="{'k-button-rectangle': !isMultiFilter}"
11288
+ [icon]="getButtonIcon('reset', 'icon')"
11289
+ [svgIcon]="getButtonIcon('reset', 'svgIcon')"
10879
11290
  (keydown.tab)="onTab($event, 'reset')">{{clearText}}</button>
10880
11291
  </div>
10881
11292
  </div>
10882
11293
  </form>
10883
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: FilterMenuHostDirective, selector: "[kendoFilterMenuHost]", inputs: ["filterService", "menuTabbingService"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
11294
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: FilterMenuHostDirective, selector: "[kendoFilterMenuHost]", inputs: ["filterService", "menuTabbingService"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MultiCheckboxFilterComponent, selector: "kendo-grid-multicheckbox-filter", inputs: ["column"], outputs: ["filterChange"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
10884
11295
  }
10885
11296
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterMenuContainerComponent, decorators: [{
10886
11297
  type: Component,
@@ -10892,17 +11303,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
10892
11303
  selector: 'kendo-grid-filter-menu-container',
10893
11304
  template: `
10894
11305
  <form (submit)="submit()" (reset)="reset()"
10895
- class="k-filter-menu">
11306
+ class="k-filter-menu"
11307
+ [ngClass]="{'k-popup k-group k-reset': isMultiFilter && !ctx.grid?.isActionSheetExpanded}">
10896
11308
  <div class="k-filter-menu-container">
10897
11309
  <ng-container [ngSwitch]="hasTemplate">
10898
11310
  <ng-container *ngSwitchCase="false">
10899
- <ng-container
11311
+ <ng-container *ngIf="!isMultiFilter; else multiFilter"
10900
11312
  kendoFilterMenuHost
10901
11313
  [filterService]="childService"
10902
11314
  [column]="column"
10903
11315
  [filter]="childFilter"
10904
11316
  [menuTabbingService]="menuTabbingService">
10905
11317
  </ng-container>
11318
+ <ng-template #multiFilter>
11319
+ <kendo-grid-multicheckbox-filter [column]="column" (filterChange)="onCheckboxFilterChange($event)"></kendo-grid-multicheckbox-filter>
11320
+ </ng-template>
10906
11321
  </ng-container>
10907
11322
  <ng-container *ngSwitchCase="true">
10908
11323
  <ng-template
@@ -10914,22 +11329,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
10914
11329
  </ng-container>
10915
11330
  </ng-container>
10916
11331
  <div *ngIf="!ctx.grid?.isActionSheetExpanded" [ngClass]="actionsClass">
10917
- <button #filterButton
11332
+ <button #filterButton kendoButton
11333
+ themeColor="primary"
10918
11334
  type="submit"
10919
- class="k-button k-button-solid-primary k-button-solid k-button-md k-rounded-md k-button-rectangle"
11335
+ [ngClass]="{'k-button-rectangle': !isMultiFilter}"
10920
11336
  [disabled]="disabled"
11337
+ [icon]="getButtonIcon('filter', 'icon')"
11338
+ [svgIcon]="getButtonIcon('filter', 'svgIcon')"
10921
11339
  (keydown.tab)="onTab($event, 'filter')">{{filterText}}</button>
10922
- <button
10923
- #resetButton
11340
+ <button #resetButton kendoButton
10924
11341
  type="reset"
10925
- class="k-button k-button-solid-base k-button-solid k-button-md k-rounded-md k-button-rectangle"
11342
+ [ngClass]="{'k-button-rectangle': !isMultiFilter}"
11343
+ [icon]="getButtonIcon('reset', 'icon')"
11344
+ [svgIcon]="getButtonIcon('reset', 'svgIcon')"
10926
11345
  (keydown.tab)="onTab($event, 'reset')">{{clearText}}</button>
10927
11346
  </div>
10928
11347
  </div>
10929
11348
  </form>
10930
11349
  `,
10931
11350
  standalone: true,
10932
- imports: [FormsModule, NgSwitch, NgSwitchCase, FilterMenuHostDirective, NgIf, NgTemplateOutlet, NgClass]
11351
+ imports: [FormsModule, NgSwitch, NgSwitchCase, FilterMenuHostDirective, NgIf, NgTemplateOutlet, NgClass, MultiCheckboxFilterComponent, ButtonComponent]
10933
11352
  }]
10934
11353
  }], ctorParameters: function () { return [{ type: FilterService, decorators: [{
10935
11354
  type: SkipSelf
@@ -10950,9 +11369,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
10950
11369
  }], resetButton: [{
10951
11370
  type: ViewChild,
10952
11371
  args: ['resetButton', { static: false }]
10953
- }], filterButton: [{
10954
- type: ViewChild,
10955
- args: ['filterButton', { static: false }]
10956
11372
  }] } });
10957
11373
 
10958
11374
  let id$1 = 0;
@@ -10968,7 +11384,6 @@ class FilterMenuComponent {
10968
11384
  renderer;
10969
11385
  cdr;
10970
11386
  adaptiveGridService;
10971
- zone;
10972
11387
  idService;
10973
11388
  filterIcon = filterIcon;
10974
11389
  /**
@@ -10986,7 +11401,7 @@ class FilterMenuComponent {
10986
11401
  tabIndex = '-1';
10987
11402
  popupRef;
10988
11403
  popupSubs;
10989
- constructor(filterService, popupService, ctx, navigationService, renderer, cdr, adaptiveGridService, zone, idService) {
11404
+ constructor(filterService, popupService, ctx, navigationService, renderer, cdr, adaptiveGridService, idService) {
10990
11405
  this.filterService = filterService;
10991
11406
  this.popupService = popupService;
10992
11407
  this.ctx = ctx;
@@ -10994,7 +11409,6 @@ class FilterMenuComponent {
10994
11409
  this.renderer = renderer;
10995
11410
  this.cdr = cdr;
10996
11411
  this.adaptiveGridService = adaptiveGridService;
10997
- this.zone = zone;
10998
11412
  this.idService = idService;
10999
11413
  }
11000
11414
  ngOnDestroy() {
@@ -11072,9 +11486,15 @@ class FilterMenuComponent {
11072
11486
  this.cdr.markForCheck();
11073
11487
  }
11074
11488
  focusRoot() {
11075
- this.isNavigable ? this.navigationService.focusCell(0, this.column.leafIndex) : this.anchor.nativeElement.focus();
11489
+ if (this.isNavigable) {
11490
+ this.navigationService.preventScroll = true;
11491
+ this.navigationService.focusCell(0, this.column.leafIndex);
11492
+ }
11493
+ else {
11494
+ this.anchor.nativeElement.focus({ preventScroll: true });
11495
+ }
11076
11496
  }
11077
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterMenuComponent, deps: [{ token: FilterService }, { token: SinglePopupService }, { token: ContextService }, { token: NavigationService }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: AdaptiveGridService }, { token: i0.NgZone }, { token: IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
11497
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FilterMenuComponent, deps: [{ token: FilterService }, { token: SinglePopupService }, { token: ContextService }, { token: NavigationService }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: AdaptiveGridService }, { token: IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
11078
11498
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FilterMenuComponent, isStandalone: true, selector: "kendo-grid-filter-menu", inputs: { column: "column", filter: "filter", tabIndex: "tabIndex" }, viewQueries: [{ propertyName: "anchor", first: true, predicate: ["anchor"], descendants: true, static: true }, { propertyName: "template", first: true, predicate: ["template"], descendants: true, read: TemplateRef, static: true }], ngImport: i0, template: `
11079
11499
  <a #anchor
11080
11500
  class="k-grid-filter-menu k-grid-header-menu"
@@ -11133,7 +11553,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
11133
11553
  standalone: true,
11134
11554
  imports: [IconWrapperComponent, FilterMenuContainerComponent],
11135
11555
  }]
11136
- }], ctorParameters: function () { return [{ type: FilterService }, { type: SinglePopupService }, { type: ContextService }, { type: NavigationService }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: AdaptiveGridService }, { type: i0.NgZone }, { type: IdService, decorators: [{
11556
+ }], ctorParameters: function () { return [{ type: FilterService }, { type: SinglePopupService }, { type: ContextService }, { type: NavigationService }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: AdaptiveGridService }, { type: IdService, decorators: [{
11137
11557
  type: Optional
11138
11558
  }] }]; }, propDecorators: { column: [{
11139
11559
  type: Input
@@ -12087,7 +12507,7 @@ class ColumnListKeyboardNavigation {
12087
12507
  toggle(index, active) {
12088
12508
  const element = this.items[index]?.hostElement.nativeElement.closest('.k-column-list-item');
12089
12509
  element && this.renderer.setAttribute(element, 'tabindex', active ? '0' : '-1');
12090
- active && element?.focus();
12510
+ active && element?.focus({ preventScroll: true });
12091
12511
  }
12092
12512
  toggleCheckedState() {
12093
12513
  this.items[this.activeIndex].hostElement.nativeElement.closest('.k-column-list-item').firstElementChild.click();
@@ -12217,15 +12637,6 @@ class ColumnListComponent {
12217
12637
  this.service.menuTabbingService.lastFocusable = this.applyButton.nativeElement;
12218
12638
  }
12219
12639
  }
12220
- onSelectAllClick(e) {
12221
- if (e.target.classList.contains('k-checkbox')) {
12222
- return;
12223
- }
12224
- e.preventDefault();
12225
- const label = e.target.closest('.k-column-list-item');
12226
- const input = label?.querySelector('input');
12227
- input.click();
12228
- }
12229
12640
  onSelectAllCheckboxChange(checkedState) {
12230
12641
  if (!checkedState && !this.allowHideAll) {
12231
12642
  const columnsToKeep = [];
@@ -12407,25 +12818,6 @@ class ColumnListComponent {
12407
12818
  });
12408
12819
  }
12409
12820
  }
12410
- checkBoxClick(e) {
12411
- const closestItem = e.target.closest('.k-column-list-item');
12412
- if (!closestItem)
12413
- return;
12414
- const checkboxElement = closestItem.querySelector('.k-checkbox-wrap');
12415
- const input = checkboxElement?.querySelector('input');
12416
- if (e.target === input) {
12417
- return;
12418
- }
12419
- e.preventDefault();
12420
- if (input) {
12421
- const index = parseInt(input.getAttribute('data-index'), 10);
12422
- const column = this.filteredColumns[index];
12423
- const isDisabled = checkboxElement.classList.contains('k-disabled');
12424
- if (column && !isDisabled) {
12425
- input.click();
12426
- }
12427
- }
12428
- }
12429
12821
  onCheckboxChange(checkedState, column, _index) {
12430
12822
  column.currentlyChecked = checkedState;
12431
12823
  if (this.autoSync) {
@@ -12459,9 +12851,7 @@ class ColumnListComponent {
12459
12851
  <label
12460
12852
  *ngIf="showSelectAll"
12461
12853
  class='k-column-list-item'
12462
- role="option"
12463
- [kendoEventsOutsideAngular]="{click: onSelectAllClick}"
12464
- [scope]="this">
12854
+ role="option">
12465
12855
  <kendo-checkbox
12466
12856
  #checkbox
12467
12857
  [inputAttributes]="{'data-index': '0'}"
@@ -12474,9 +12864,7 @@ class ColumnListComponent {
12474
12864
  <label
12475
12865
  *ngFor="let column of filteredColumns; let index = index;"
12476
12866
  class='k-column-list-item'
12477
- role="option"
12478
- [kendoEventsOutsideAngular]="{click: checkBoxClick}"
12479
- [scope]="this">
12867
+ role="option">
12480
12868
  <kendo-checkbox
12481
12869
  #checkbox
12482
12870
  [inputAttributes]="{'data-index': index.toString()}"
@@ -12487,7 +12875,7 @@ class ColumnListComponent {
12487
12875
  <span class="k-checkbox-label">{{ column.displayTitle }}</span>
12488
12876
  </label>
12489
12877
  </div>
12490
- `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CheckBoxComponent, selector: "kendo-checkbox", inputs: ["checkedState", "rounded"], outputs: ["checkedStateChange"], exportAs: ["kendoCheckBox"] }, { kind: "directive", type: EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }] });
12878
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CheckBoxComponent, selector: "kendo-checkbox", inputs: ["checkedState", "rounded"], outputs: ["checkedStateChange"], exportAs: ["kendoCheckBox"] }] });
12491
12879
  }
12492
12880
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnListComponent, decorators: [{
12493
12881
  type: Component,
@@ -12503,9 +12891,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
12503
12891
  <label
12504
12892
  *ngIf="showSelectAll"
12505
12893
  class='k-column-list-item'
12506
- role="option"
12507
- [kendoEventsOutsideAngular]="{click: onSelectAllClick}"
12508
- [scope]="this">
12894
+ role="option">
12509
12895
  <kendo-checkbox
12510
12896
  #checkbox
12511
12897
  [inputAttributes]="{'data-index': '0'}"
@@ -12518,9 +12904,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
12518
12904
  <label
12519
12905
  *ngFor="let column of filteredColumns; let index = index;"
12520
12906
  class='k-column-list-item'
12521
- role="option"
12522
- [kendoEventsOutsideAngular]="{click: checkBoxClick}"
12523
- [scope]="this">
12907
+ role="option">
12524
12908
  <kendo-checkbox
12525
12909
  #checkbox
12526
12910
  [inputAttributes]="{'data-index': index.toString()}"
@@ -12533,7 +12917,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
12533
12917
  </div>
12534
12918
  `,
12535
12919
  standalone: true,
12536
- imports: [NgFor, NgIf, CheckBoxComponent, EventsOutsideAngularDirective]
12920
+ imports: [NgFor, NgIf, CheckBoxComponent]
12537
12921
  }]
12538
12922
  }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: ColumnListKeyboardNavigation }, { type: i0.ChangeDetectorRef }, { type: ColumnInfoService, decorators: [{
12539
12923
  type: Optional
@@ -13375,7 +13759,7 @@ class ColumnChooserToolbarDirective extends ToolbarToolBase {
13375
13759
  this.buttonElement?.setAttribute('aria-expanded', 'false');
13376
13760
  this.buttonElement?.removeAttribute('aria-controls');
13377
13761
  this.host.selected = false;
13378
- focusAnchor && this.buttonElement?.focus();
13762
+ focusAnchor && this.buttonElement?.focus({ preventScroll: true });
13379
13763
  }
13380
13764
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnChooserToolbarDirective, deps: [{ token: i0.Renderer2 }, { token: i2.PopupService }, { token: i54.ToolBarButtonComponent }, { token: ContextService }, { token: i0.NgZone }, { token: i54.RefreshService }, { token: AdaptiveGridService }, { token: ColumnInfoService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
13381
13765
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ColumnChooserToolbarDirective, isStandalone: true, selector: "[kendoGridColumnChooserTool]", inputs: { autoSync: "autoSync", allowHideAll: "allowHideAll", filterable: "filterable", showSelectAll: "showSelectAll" }, usesInheritance: true, ngImport: i0 });
@@ -14899,7 +15283,15 @@ class ColumnMenuContainerComponent {
14899
15283
  else {
14900
15284
  return;
14901
15285
  }
14902
- this.ngZone.onStable.pipe(take(1)).subscribe(() => this.service.menuTabbingService.firstFocusable?.focus());
15286
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => {
15287
+ const firstFocusable = this.service.menuTabbingService.firstFocusable;
15288
+ if (firstFocusable instanceof DropDownListComponent) {
15289
+ firstFocusable.wrapper.nativeElement.focus({ preventScroll: true });
15290
+ }
15291
+ else {
15292
+ firstFocusable?.focus({ preventScroll: true });
15293
+ }
15294
+ });
14903
15295
  }
14904
15296
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuContainerComponent, deps: [{ token: ColumnMenuService }, { token: NgZone }], target: i0.ɵɵFactoryTarget.Component });
14905
15297
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuContainerComponent, isStandalone: true, selector: "kendo-grid-columnmenu-container", queries: [{ propertyName: "columnMenuItems", predicate: ColumnMenuItemDirective, descendants: true }], ngImport: i0, template: `
@@ -15354,7 +15746,13 @@ class ColumnMenuComponent {
15354
15746
  ariaRoot && this.renderer.setAttribute(ariaRoot, 'aria-expanded', 'false');
15355
15747
  }
15356
15748
  focusRoot() {
15357
- this.isNavigable ? this.navigationService.focusCell(0, this.column.leafIndex) : this.anchor.nativeElement.focus();
15749
+ if (this.isNavigable) {
15750
+ this.navigationService.preventScroll = true;
15751
+ this.navigationService.focusCell(0, this.column.leafIndex);
15752
+ }
15753
+ else {
15754
+ this.anchor.nativeElement.focus({ preventScroll: true });
15755
+ }
15358
15756
  }
15359
15757
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuComponent, deps: [{ token: NavigationService }, { token: SinglePopupService }, { token: ColumnMenuService }, { token: ContextService }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: ColumnInfoService }, { token: IdService, optional: true }, { token: AdaptiveGridService }], target: i0.ɵɵFactoryTarget.Component });
15360
15758
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuComponent, isStandalone: true, selector: "kendo-grid-column-menu", inputs: { standalone: "standalone", column: "column", settings: "settings", sort: "sort", filter: "filter", sortable: "sortable", columnMenuTemplate: "columnMenuTemplate", tabIndex: "tabIndex" }, host: { properties: { "class.k-grid-column-menu-standalone": "this.standalone" } }, providers: [
@@ -16503,11 +16901,16 @@ class PDFComponent extends PDFExportComponent {
16503
16901
  overlayContent.scrollTop = content.scrollTop;
16504
16902
  overlayContent.scrollLeft = content.scrollLeft;
16505
16903
  if (!this.ctx?.grid?.isStacked) {
16506
- overlayQuery.header().scrollLeft = query.header().scrollLeft;
16904
+ const header = query.header();
16905
+ const overlayHeader = overlayQuery.header();
16906
+ if (header && overlayHeader) {
16907
+ overlayHeader.scrollLeft = header.scrollLeft;
16908
+ }
16507
16909
  }
16508
16910
  const footer = query.footer();
16509
- if (footer) {
16510
- overlayQuery.footer().scrollLeft = footer.scrollLeft;
16911
+ const overlayFooter = overlayQuery.footer();
16912
+ if (footer && overlayFooter) {
16913
+ overlayFooter.scrollLeft = footer.scrollLeft;
16511
16914
  }
16512
16915
  const lockedContent = query.content(true);
16513
16916
  if (lockedContent) {
@@ -17258,19 +17661,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
17258
17661
  args: ['dblclick']
17259
17662
  }] } });
17260
17663
 
17261
- /**
17262
- * @hidden
17263
- */
17264
- class LocalDataChangesService {
17265
- changes = new EventEmitter();
17266
- data;
17267
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalDataChangesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
17268
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalDataChangesService });
17269
- }
17270
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalDataChangesService, decorators: [{
17271
- type: Injectable
17272
- }] });
17273
-
17274
17664
  /**
17275
17665
  * @hidden
17276
17666
  */
@@ -18491,7 +18881,7 @@ class HeaderComponent {
18491
18881
  }
18492
18882
  onHeaderKeydown(column, args) {
18493
18883
  const code = normalizeNumpadKeys(args);
18494
- if (code === Keys.ArrowDown && args.altKey && this.showFilterMenu) {
18884
+ if (code === Keys.ArrowDown && args.altKey && this.showFilterMenu && this.isFilterable(column)) {
18495
18885
  args.preventDefault();
18496
18886
  args.stopImmediatePropagation();
18497
18887
  const filterMenu = this.filterMenus.find(fm => fm.column === column);
@@ -19549,7 +19939,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
19549
19939
 
19550
19940
  /**
19551
19941
  * Represents the command columns of the Grid. Define the content of the column inside an `<ng-template>` tag.
19552
- * For more information and examples, see the [Command Column Directives](slug:editing_directives_grid#toc-command-column-directives) article.
19942
+ * For more information and examples, see the [Editing Action Buttons](slug:basics_editing_grid#editing-action-buttons) article.
19553
19943
  *
19554
19944
  * @example
19555
19945
  * ```html
@@ -20190,7 +20580,7 @@ class CellComponent {
20190
20580
  </ng-container>
20191
20581
  </div>
20192
20582
  </div>
20193
- <div class="k-grid-stack-cell" *ngIf="detailTemplate?.showIf(item.data, $any(item).index)">
20583
+ <div class="k-grid-stack-cell" *ngIf="detailTemplate?.showIf(item.data, $any(item).index)" [attr.aria-expanded]="item.isExpanded">
20194
20584
  <div class="k-grid-stack-content">
20195
20585
  <button kendoButton
20196
20586
  fillMode="flat"
@@ -20398,7 +20788,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
20398
20788
  </ng-container>
20399
20789
  </div>
20400
20790
  </div>
20401
- <div class="k-grid-stack-cell" *ngIf="detailTemplate?.showIf(item.data, $any(item).index)">
20791
+ <div class="k-grid-stack-cell" *ngIf="detailTemplate?.showIf(item.data, $any(item).index)" [attr.aria-expanded]="item.isExpanded">
20402
20792
  <div class="k-grid-stack-content">
20403
20793
  <button kendoButton
20404
20794
  fillMode="flat"
@@ -21121,7 +21511,8 @@ class TableBodyComponent {
21121
21511
  [dataItem]="item.data"
21122
21512
  [detailExpandCell]="true"
21123
21513
  aria-selected="false"
21124
- role="gridcell">
21514
+ role="gridcell"
21515
+ [attr.aria-expanded]="item.isExpanded">
21125
21516
  <a
21126
21517
  *ngIf="detailTemplate.showIf(item.data, $any(item).index)"
21127
21518
  [attr.title]="detailButtonTitle(item)"
@@ -21441,7 +21832,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
21441
21832
  [dataItem]="item.data"
21442
21833
  [detailExpandCell]="true"
21443
21834
  aria-selected="false"
21444
- role="gridcell">
21835
+ role="gridcell"
21836
+ [attr.aria-expanded]="item.isExpanded">
21445
21837
  <a
21446
21838
  *ngIf="detailTemplate.showIf(item.data, $any(item).index)"
21447
21839
  [attr.title]="detailButtonTitle(item)"
@@ -21796,7 +22188,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
21796
22188
  /**
21797
22189
  * Represents the `cancel` command of the Grid. Apply this directive to any `button`
21798
22190
  * element inside a [CommandColumnComponent]({% slug api_grid_commandcolumncomponent %})
21799
- * ([see example](slug:editing_directives_grid#toc-command-column-directives)).
22191
+ * ([see example](slug:basics_editing_grid#editing-action-buttons)).
21800
22192
  *
21801
22193
  * When a button with this directive is clicked, the
21802
22194
  * [`cancel`]({% slug api_grid_gridcomponent %}#toc-cancel) event
@@ -21900,7 +22292,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
21900
22292
  /**
21901
22293
  * Represents the `save` command of the Grid. Apply this directive to any `button`
21902
22294
  * element inside a [CommandColumnComponent]({% slug api_grid_commandcolumncomponent %})
21903
- * ([see example](slug:editing_directives_grid#toc-command-column-directives)).
22295
+ * ([see example](slug:basics_editing_grid#editing-action-buttons)).
21904
22296
  * When you click the button with this directive, the
21905
22297
  * [`save`]({% slug api_grid_gridcomponent %}#toc-save) event fires.
21906
22298
  * The button with `kendoGridSaveCommand` is automatically hidden when the row is not in edit mode.
@@ -22003,7 +22395,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
22003
22395
  /**
22004
22396
  * Represents the `remove` command of the Grid. Apply this directive to any `button` element
22005
22397
  * inside a [CommandColumnComponent]({% slug api_grid_commandcolumncomponent %})
22006
- * ([see example](slug:editing_directives_grid#toc-command-column-directives)).
22398
+ * ([see example](slug:basics_editing_grid#editing-action-buttons)).
22007
22399
  * When you click the button with this directive, the
22008
22400
  * [`remove`]({% slug api_grid_gridcomponent %}#toc-remove) event fires.
22009
22401
  * The button with `kendoGridRemoveCommand` is automatically hidden when the row is in edit mode.
@@ -22427,8 +22819,8 @@ const packageMetadata = {
22427
22819
  productName: 'Kendo UI for Angular',
22428
22820
  productCode: 'KENDOUIANGULAR',
22429
22821
  productCodes: ['KENDOUIANGULAR'],
22430
- publishDate: 1758189236,
22431
- version: '20.1.0-develop.3',
22822
+ publishDate: 1760682423,
22823
+ version: '20.1.0-develop.31',
22432
22824
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
22433
22825
  };
22434
22826
 
@@ -24389,9 +24781,6 @@ class ScrollerService {
24389
24781
  const lastItemIndex = this.rowHeightService.index(scrollTop + offsetHeight);
24390
24782
  const overflow = Math.max(firstItemIndex + (this.virtualPageSize || this.take) - this.total, 0);
24391
24783
  firstItemIndex = Math.max(firstItemIndex - overflow, 0);
24392
- if (lastItemIndex < this.lastLoaded) {
24393
- this.lastLoaded = lastItemIndex;
24394
- }
24395
24784
  if (down) {
24396
24785
  const atBottom = scrollHeight - clientHeight - scrollTop < SCROLL_BOTTOM_THRESHOLD;
24397
24786
  if (atBottom) {
@@ -25587,7 +25976,7 @@ class ListComponent {
25587
25976
  <div></div>
25588
25977
  </div>
25589
25978
  </div>
25590
- <div
25979
+ <div
25591
25980
  #container
25592
25981
  class="k-grid-content k-virtual-content"
25593
25982
  [kendoGridResizableContainer]="lockedLeafColumns.length > 0"
@@ -25712,7 +26101,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
25712
26101
  <div></div>
25713
26102
  </div>
25714
26103
  </div>
25715
- <div
26104
+ <div
25716
26105
  #container
25717
26106
  class="k-grid-content k-virtual-content"
25718
26107
  [kendoGridResizableContainer]="lockedLeafColumns.length > 0"
@@ -26577,8 +26966,29 @@ class GridMessages extends ComponentMessages {
26577
26966
  * Sets the text for the external editing Dialog <b>Cancel</b> button.
26578
26967
  */
26579
26968
  externalEditingCancelText;
26969
+ /**
26970
+ * The placeholder text for the multi-checkbox filter search input
26971
+ */
26972
+ multiCheckboxFilterSearchPlaceholder;
26973
+ /**
26974
+ * The label for the multi-checkbox filter select all option
26975
+ */
26976
+ multiCheckboxFilterSelectAllLabel;
26977
+ /**
26978
+ * The text for the multi-checkbox filter selected items count
26979
+ *
26980
+ * The text includes the selected items count and a localizable string.
26981
+ * For 3 selected items the default text is `3 selected items`.
26982
+ *
26983
+ * To customize the text, use the `{selectedItemsCount}` placeholder and a custom localizable string.
26984
+ * For example, `{selectedItemsCount} items are selected`.
26985
+ *
26986
+ * The `{selectedItemsCount}` placeholder is replaced with the count of selected items,
26987
+ * and the message is rendered as `3 items are selected`.
26988
+ */
26989
+ multiCheckboxFilterSelectedItemsCount;
26580
26990
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GridMessages, deps: null, target: i0.ɵɵFactoryTarget.Directive });
26581
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GridMessages, selector: "kendo-grid-messages-base", inputs: { groupPanelEmpty: "groupPanelEmpty", noRecords: "noRecords", pagerLabel: "pagerLabel", pagerFirstPage: "pagerFirstPage", pagerLastPage: "pagerLastPage", pagerPreviousPage: "pagerPreviousPage", pagerNextPage: "pagerNextPage", pagerPage: "pagerPage", pagerItemsPerPage: "pagerItemsPerPage", pagerOf: "pagerOf", pagerItems: "pagerItems", pagerPageNumberInputTitle: "pagerPageNumberInputTitle", pagerInputLabel: "pagerInputLabel", pagerSelectPage: "pagerSelectPage", filter: "filter", filterInputLabel: "filterInputLabel", filterMenuTitle: "filterMenuTitle", filterMenuOperatorsDropDownLabel: "filterMenuOperatorsDropDownLabel", filterMenuLogicDropDownLabel: "filterMenuLogicDropDownLabel", filterCellOperatorLabel: "filterCellOperatorLabel", booleanFilterCellLabel: "booleanFilterCellLabel", aiAssistantApplyButtonText: "aiAssistantApplyButtonText", aiAssistantToolbarToolText: "aiAssistantToolbarToolText", aiAssistantWindowTitle: "aiAssistantWindowTitle", aiAssistantWindowCloseTitle: "aiAssistantWindowCloseTitle", aiAssistantOutputCardTitle: "aiAssistantOutputCardTitle", aiAssistantOutputCardBodyContent: "aiAssistantOutputCardBodyContent", aiAssistantWindowMaximizeTitle: "aiAssistantWindowMaximizeTitle", aiAssistantWindowMinimizeTitle: "aiAssistantWindowMinimizeTitle", aiAssistantWindowRestoreTitle: "aiAssistantWindowRestoreTitle", filterEqOperator: "filterEqOperator", filterNotEqOperator: "filterNotEqOperator", filterIsNullOperator: "filterIsNullOperator", filterIsNotNullOperator: "filterIsNotNullOperator", filterIsEmptyOperator: "filterIsEmptyOperator", filterIsNotEmptyOperator: "filterIsNotEmptyOperator", filterStartsWithOperator: "filterStartsWithOperator", filterContainsOperator: "filterContainsOperator", filterNotContainsOperator: "filterNotContainsOperator", filterEndsWithOperator: "filterEndsWithOperator", filterGteOperator: "filterGteOperator", filterGtOperator: "filterGtOperator", filterLteOperator: "filterLteOperator", filterLtOperator: "filterLtOperator", filterIsTrue: "filterIsTrue", filterIsFalse: "filterIsFalse", filterBooleanAll: "filterBooleanAll", adaptiveFilterOperatorsTitle: "adaptiveFilterOperatorsTitle", filterAfterOrEqualOperator: "filterAfterOrEqualOperator", filterAfterOperator: "filterAfterOperator", filterBeforeOperator: "filterBeforeOperator", filterBeforeOrEqualOperator: "filterBeforeOrEqualOperator", filterFilterButton: "filterFilterButton", filterClearButton: "filterClearButton", adaptiveCloseButtonTitle: "adaptiveCloseButtonTitle", adaptiveBackButtonTitle: "adaptiveBackButtonTitle", filterAndLogic: "filterAndLogic", filterOrLogic: "filterOrLogic", filterToolbarToolText: "filterToolbarToolText", loading: "loading", gridLabel: "gridLabel", columnMenu: "columnMenu", setColumnPosition: "setColumnPosition", columns: "columns", columnChooserSelectedColumnsCount: "columnChooserSelectedColumnsCount", columnsSubtitle: "columnsSubtitle", adaptiveFilterTitle: "adaptiveFilterTitle", adaptiveSortTitle: "adaptiveSortTitle", adaptiveGroupTitle: "adaptiveGroupTitle", filterClearAllButton: "filterClearAllButton", groupClearButton: "groupClearButton", sortClearButton: "sortClearButton", sortDoneButton: "sortDoneButton", groupDoneButton: "groupDoneButton", lock: "lock", unlock: "unlock", stick: "stick", unstick: "unstick", sortable: "sortable", sortAscending: "sortAscending", sortDescending: "sortDescending", autosizeThisColumn: "autosizeThisColumn", autosizeAllColumns: "autosizeAllColumns", sortedAscending: "sortedAscending", sortedDescending: "sortedDescending", sortedDefault: "sortedDefault", sortToolbarToolText: "sortToolbarToolText", columnsApply: "columnsApply", columnsReset: "columnsReset", detailExpand: "detailExpand", detailCollapse: "detailCollapse", filterDateToday: "filterDateToday", filterDateToggle: "filterDateToggle", filterNumericDecrement: "filterNumericDecrement", filterNumericIncrement: "filterNumericIncrement", selectionCheckboxLabel: "selectionCheckboxLabel", selectAllCheckboxLabel: "selectAllCheckboxLabel", groupCollapse: "groupCollapse", groupExpand: "groupExpand", topToolbarLabel: "topToolbarLabel", bottomToolbarLabel: "bottomToolbarLabel", editToolbarToolText: "editToolbarToolText", saveToolbarToolText: "saveToolbarToolText", addToolbarToolText: "addToolbarToolText", cancelToolbarToolText: "cancelToolbarToolText", removeToolbarToolText: "removeToolbarToolText", excelExportToolbarToolText: "excelExportToolbarToolText", pdfExportToolbarToolText: "pdfExportToolbarToolText", groupPanelLabel: "groupPanelLabel", dragRowHandleLabel: "dragRowHandleLabel", columnMenuFilterTabTitle: "columnMenuFilterTabTitle", columnMenuGeneralTabTitle: "columnMenuGeneralTabTitle", columnMenuColumnsTabTitle: "columnMenuColumnsTabTitle", groupChipMenuPrevious: "groupChipMenuPrevious", groupChipMenuNext: "groupChipMenuNext", groupToolbarToolText: "groupToolbarToolText", formValidationErrorText: "formValidationErrorText", removeConfirmationDialogTitle: "removeConfirmationDialogTitle", removeConfirmationDialogContent: "removeConfirmationDialogContent", removeConfirmationDialogConfirmText: "removeConfirmationDialogConfirmText", removeConfirmationDialogRejectText: "removeConfirmationDialogRejectText", externalEditingTitle: "externalEditingTitle", externalEditingAddTitle: "externalEditingAddTitle", externalEditingSaveText: "externalEditingSaveText", externalEditingCancelText: "externalEditingCancelText" }, usesInheritance: true, ngImport: i0 });
26991
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GridMessages, selector: "kendo-grid-messages-base", inputs: { groupPanelEmpty: "groupPanelEmpty", noRecords: "noRecords", pagerLabel: "pagerLabel", pagerFirstPage: "pagerFirstPage", pagerLastPage: "pagerLastPage", pagerPreviousPage: "pagerPreviousPage", pagerNextPage: "pagerNextPage", pagerPage: "pagerPage", pagerItemsPerPage: "pagerItemsPerPage", pagerOf: "pagerOf", pagerItems: "pagerItems", pagerPageNumberInputTitle: "pagerPageNumberInputTitle", pagerInputLabel: "pagerInputLabel", pagerSelectPage: "pagerSelectPage", filter: "filter", filterInputLabel: "filterInputLabel", filterMenuTitle: "filterMenuTitle", filterMenuOperatorsDropDownLabel: "filterMenuOperatorsDropDownLabel", filterMenuLogicDropDownLabel: "filterMenuLogicDropDownLabel", filterCellOperatorLabel: "filterCellOperatorLabel", booleanFilterCellLabel: "booleanFilterCellLabel", aiAssistantApplyButtonText: "aiAssistantApplyButtonText", aiAssistantToolbarToolText: "aiAssistantToolbarToolText", aiAssistantWindowTitle: "aiAssistantWindowTitle", aiAssistantWindowCloseTitle: "aiAssistantWindowCloseTitle", aiAssistantOutputCardTitle: "aiAssistantOutputCardTitle", aiAssistantOutputCardBodyContent: "aiAssistantOutputCardBodyContent", aiAssistantWindowMaximizeTitle: "aiAssistantWindowMaximizeTitle", aiAssistantWindowMinimizeTitle: "aiAssistantWindowMinimizeTitle", aiAssistantWindowRestoreTitle: "aiAssistantWindowRestoreTitle", filterEqOperator: "filterEqOperator", filterNotEqOperator: "filterNotEqOperator", filterIsNullOperator: "filterIsNullOperator", filterIsNotNullOperator: "filterIsNotNullOperator", filterIsEmptyOperator: "filterIsEmptyOperator", filterIsNotEmptyOperator: "filterIsNotEmptyOperator", filterStartsWithOperator: "filterStartsWithOperator", filterContainsOperator: "filterContainsOperator", filterNotContainsOperator: "filterNotContainsOperator", filterEndsWithOperator: "filterEndsWithOperator", filterGteOperator: "filterGteOperator", filterGtOperator: "filterGtOperator", filterLteOperator: "filterLteOperator", filterLtOperator: "filterLtOperator", filterIsTrue: "filterIsTrue", filterIsFalse: "filterIsFalse", filterBooleanAll: "filterBooleanAll", adaptiveFilterOperatorsTitle: "adaptiveFilterOperatorsTitle", filterAfterOrEqualOperator: "filterAfterOrEqualOperator", filterAfterOperator: "filterAfterOperator", filterBeforeOperator: "filterBeforeOperator", filterBeforeOrEqualOperator: "filterBeforeOrEqualOperator", filterFilterButton: "filterFilterButton", filterClearButton: "filterClearButton", adaptiveCloseButtonTitle: "adaptiveCloseButtonTitle", adaptiveBackButtonTitle: "adaptiveBackButtonTitle", filterAndLogic: "filterAndLogic", filterOrLogic: "filterOrLogic", filterToolbarToolText: "filterToolbarToolText", loading: "loading", gridLabel: "gridLabel", columnMenu: "columnMenu", setColumnPosition: "setColumnPosition", columns: "columns", columnChooserSelectedColumnsCount: "columnChooserSelectedColumnsCount", columnsSubtitle: "columnsSubtitle", adaptiveFilterTitle: "adaptiveFilterTitle", adaptiveSortTitle: "adaptiveSortTitle", adaptiveGroupTitle: "adaptiveGroupTitle", filterClearAllButton: "filterClearAllButton", groupClearButton: "groupClearButton", sortClearButton: "sortClearButton", sortDoneButton: "sortDoneButton", groupDoneButton: "groupDoneButton", lock: "lock", unlock: "unlock", stick: "stick", unstick: "unstick", sortable: "sortable", sortAscending: "sortAscending", sortDescending: "sortDescending", autosizeThisColumn: "autosizeThisColumn", autosizeAllColumns: "autosizeAllColumns", sortedAscending: "sortedAscending", sortedDescending: "sortedDescending", sortedDefault: "sortedDefault", sortToolbarToolText: "sortToolbarToolText", columnsApply: "columnsApply", columnsReset: "columnsReset", detailExpand: "detailExpand", detailCollapse: "detailCollapse", filterDateToday: "filterDateToday", filterDateToggle: "filterDateToggle", filterNumericDecrement: "filterNumericDecrement", filterNumericIncrement: "filterNumericIncrement", selectionCheckboxLabel: "selectionCheckboxLabel", selectAllCheckboxLabel: "selectAllCheckboxLabel", groupCollapse: "groupCollapse", groupExpand: "groupExpand", topToolbarLabel: "topToolbarLabel", bottomToolbarLabel: "bottomToolbarLabel", editToolbarToolText: "editToolbarToolText", saveToolbarToolText: "saveToolbarToolText", addToolbarToolText: "addToolbarToolText", cancelToolbarToolText: "cancelToolbarToolText", removeToolbarToolText: "removeToolbarToolText", excelExportToolbarToolText: "excelExportToolbarToolText", pdfExportToolbarToolText: "pdfExportToolbarToolText", groupPanelLabel: "groupPanelLabel", dragRowHandleLabel: "dragRowHandleLabel", columnMenuFilterTabTitle: "columnMenuFilterTabTitle", columnMenuGeneralTabTitle: "columnMenuGeneralTabTitle", columnMenuColumnsTabTitle: "columnMenuColumnsTabTitle", groupChipMenuPrevious: "groupChipMenuPrevious", groupChipMenuNext: "groupChipMenuNext", groupToolbarToolText: "groupToolbarToolText", formValidationErrorText: "formValidationErrorText", removeConfirmationDialogTitle: "removeConfirmationDialogTitle", removeConfirmationDialogContent: "removeConfirmationDialogContent", removeConfirmationDialogConfirmText: "removeConfirmationDialogConfirmText", removeConfirmationDialogRejectText: "removeConfirmationDialogRejectText", externalEditingTitle: "externalEditingTitle", externalEditingAddTitle: "externalEditingAddTitle", externalEditingSaveText: "externalEditingSaveText", externalEditingCancelText: "externalEditingCancelText", multiCheckboxFilterSearchPlaceholder: "multiCheckboxFilterSearchPlaceholder", multiCheckboxFilterSelectAllLabel: "multiCheckboxFilterSelectAllLabel", multiCheckboxFilterSelectedItemsCount: "multiCheckboxFilterSelectedItemsCount" }, usesInheritance: true, ngImport: i0 });
26582
26992
  }
26583
26993
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GridMessages, decorators: [{
26584
26994
  type: Directive,
@@ -26836,6 +27246,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
26836
27246
  type: Input
26837
27247
  }], externalEditingCancelText: [{
26838
27248
  type: Input
27249
+ }], multiCheckboxFilterSearchPlaceholder: [{
27250
+ type: Input
27251
+ }], multiCheckboxFilterSelectAllLabel: [{
27252
+ type: Input
27253
+ }], multiCheckboxFilterSelectedItemsCount: [{
27254
+ type: Input
26839
27255
  }] } });
26840
27256
 
26841
27257
  /**
@@ -26941,7 +27357,7 @@ class FilterToolbarToolComponent {
26941
27357
  }
26942
27358
  ngAfterViewInit() {
26943
27359
  this.ngZone.onStable.pipe(take(1)).subscribe(() => {
26944
- this.filterItems?.get(0)?.nativeElement.focus();
27360
+ this.filterItems?.get(0)?.nativeElement.focus({ preventScroll: true });
26945
27361
  });
26946
27362
  }
26947
27363
  ngOnDestroy() {
@@ -27127,7 +27543,7 @@ class SortToolbarToolComponent {
27127
27543
  }
27128
27544
  ngAfterViewInit() {
27129
27545
  this.ngZone.onStable.pipe(take(1)).subscribe(() => {
27130
- this.sortItems?.get(0)?.nativeElement.focus();
27546
+ this.sortItems?.get(0)?.nativeElement.focus({ preventScroll: true });
27131
27547
  });
27132
27548
  }
27133
27549
  ngOnDestroy() {
@@ -27689,12 +28105,12 @@ class GroupToolbarToolComponent {
27689
28105
  if (items?.first && (!isPresent$1(this.currentFocusedItemIndex) || this.currentFocusedItemIndex >= items.length || this.currentFocusedItemIndex < 0)) {
27690
28106
  this.ngZone.onStable.pipe(take(1)).subscribe(() => {
27691
28107
  this.currentFocusedItemIndex = 0;
27692
- this.groupItems.first.nativeElement.focus();
28108
+ this.groupItems.first.nativeElement.focus({ preventScroll: true });
27693
28109
  });
27694
28110
  return;
27695
28111
  }
27696
28112
  if (items?.first) {
27697
- items.get(this.currentFocusedItemIndex).nativeElement.focus();
28113
+ items.get(this.currentFocusedItemIndex).nativeElement.focus({ preventScroll: true });
27698
28114
  }
27699
28115
  }
27700
28116
  get groupItems() {
@@ -29214,1005 +29630,327 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
29214
29630
  args: [GroupToolbarToolComponent]
29215
29631
  }] } });
29216
29632
 
29217
- /**
29218
- * @hidden
29219
- */
29220
- const DEFAULT_AI_REQUEST_OPTIONS = {
29221
- headers: new HttpHeaders({
29222
- 'Content-Type': 'application/json'
29223
- }),
29224
- role: 'user',
29225
- method: 'POST',
29226
- responseType: 'json'
29633
+ const createControl = (source) => (acc, key) => {
29634
+ acc[key] = new FormControl(source[key]);
29635
+ return acc;
29227
29636
  };
29637
+ const validateColumnsField = (columns) => expandColumns(columns.toArray())
29638
+ .filter(isColumnComponent)
29639
+ .filter(({ field }) => !isValidFieldName(field))
29640
+ .forEach(({ field }) => console.warn(ColumnConfigurationErrorMessages.fieldName(field)));
29641
+ const handleExpandCollapseGroupsService = (service, expandEmitter, collapseEmitter, map) => (service.changes.pipe(filter(({ group, emit }) => emit && isPresent(group)))
29642
+ .subscribe((x) => x.expand ? expandEmitter.emit(map(x)) : collapseEmitter.emit(map(x))));
29643
+ const handleExpandCollapseDetailsService = (service, expandEmitter, collapseEmitter, map) => (service.changes.pipe(filter(({ dataItem }) => isPresent(dataItem)))
29644
+ .subscribe((x) => x.expand ? expandEmitter.emit(map(x)) : collapseEmitter.emit(map(x))));
29645
+ const isInEditedCell = (element, gridElement, isStacked = false) => (closest(element, matchesClasses('k-grid-edit-cell')) || (isStacked && closest(element, matchesClasses('k-grid-stack-edit-cell')))) &&
29646
+ closest(element, matchesNodeName('kendo-grid')) === gridElement;
29647
+ const NOTIFY_DELAY = 500;
29228
29648
  /**
29229
- * Represents the event data when the AI Assistant request completes successfully.
29649
+ * Represents the Kendo UI for Angular Data Grid component.
29650
+ *
29651
+ * Use the `kendo-grid` component to display and manage tabular data.
29652
+ *
29653
+ * @example
29654
+ * ```html
29655
+ * <kendo-grid [data]="gridData"></kendo-grid>
29656
+ * ```
29657
+ *
29658
+ * @remarks
29659
+ * Supported children components are:
29660
+ * {@link CheckboxColumnComponent},
29661
+ * {@link ColumnChooserComponent},
29662
+ * {@link ColumnComponent},
29663
+ * {@link ColumnGroupComponent},
29664
+ * {@link ColumnMenuAutoSizeAllColumnsComponent},
29665
+ * {@link ColumnMenuAutoSizeColumnComponent},
29666
+ * {@link ColumnMenuChooserComponent},
29667
+ * {@link ColumnMenuComponent},
29668
+ * {@link ColumnMenuFilterComponent},
29669
+ * {@link ColumnMenuItemComponent},
29670
+ * {@link ColumnMenuLockComponent},
29671
+ * {@link ColumnMenuPositionComponent},
29672
+ * {@link ColumnMenuSortComponent},
29673
+ * {@link ColumnMenuStickComponent},
29674
+ * {@link CommandColumnComponent},
29675
+ * {@link CustomMessagesComponent},
29676
+ * {@link ExcelComponent},
29677
+ * {@link GridSpacerComponent},
29678
+ * {@link PDFComponent},
29679
+ * {@link RowReorderColumnComponent},
29680
+ * {@link SpanColumnComponent},
29681
+ * {@link ToolBarComponent}.
29230
29682
  */
29231
- class GridToolbarAIResponseSuccessEvent extends PreventableEvent$1 {
29683
+ class GridComponent {
29684
+ supportService;
29685
+ selectionService;
29686
+ cellSelectionService;
29687
+ wrapper;
29688
+ groupInfoService;
29689
+ groupsService;
29690
+ changeNotification;
29691
+ detailsService;
29692
+ editService;
29693
+ filterService;
29694
+ pdfService;
29695
+ responsiveService;
29696
+ renderer;
29697
+ excelService;
29698
+ ngZone;
29699
+ scrollSyncService;
29700
+ domEvents;
29701
+ columnResizingService;
29702
+ changeDetectorRef;
29703
+ columnReorderService;
29704
+ columnInfoService;
29705
+ navigationService;
29706
+ sortService;
29707
+ scrollRequestService;
29708
+ localization;
29709
+ ctx;
29710
+ sizingService;
29711
+ adaptiveGridService;
29712
+ rowReorderService;
29713
+ dataMappingService;
29232
29714
  /**
29233
- * The HTTP response from the AI service.
29715
+ * Sets the data of the Grid. If you provide an array, the Grid gets the total count automatically.
29716
+ * ([more information and example]({% slug binding_grid %})).
29234
29717
  */
29235
- response;
29236
- constructor(response) {
29237
- super();
29238
- this.response = response;
29718
+ set data(value) {
29719
+ this._data = value;
29720
+ if (this.selectable && this.selectableSettings?.enabled && this.isVirtual) {
29721
+ this.blockArrowSelection = false;
29722
+ }
29723
+ if (this.notifyTimeout) {
29724
+ clearTimeout(this.notifyTimeout);
29725
+ this.notifyTimeout = null;
29726
+ }
29727
+ if (this.rowReorderable) {
29728
+ this.ngZone.runOutsideAngular(() => {
29729
+ this.notifyTimeout = setTimeout(() => {
29730
+ this.notifyReorderContainers();
29731
+ }, NOTIFY_DELAY);
29732
+ });
29733
+ }
29239
29734
  }
29240
- }
29241
- /**
29242
- * Represents the event data when the AI Assistant request completes with an error.
29243
- */
29244
- class GridToolbarAIResponseErrorEvent extends PreventableEvent$1 {
29245
- /**
29246
- * The HTTP error response from the AI service.
29247
- */
29248
- error;
29249
- constructor(error) {
29250
- super();
29251
- this.error = error;
29735
+ get data() {
29736
+ return this._data;
29252
29737
  }
29253
- }
29254
-
29255
- /**
29256
- * @hidden
29257
- * Converts date strings in a filter to Date objects.
29258
- */
29259
- const convertDateStringsInFilter = (filter) => {
29260
- if (!filter) {
29261
- return filter;
29738
+ get hintText() {
29739
+ return this.rowReorderService.getDefaultHintText(this.columnList, this.flatData);
29262
29740
  }
29263
- if (filter.filters && Array.isArray(filter.filters)) {
29264
- return {
29265
- ...filter,
29266
- filters: filter.filters.map(f => convertDateStringsInFilter(f))
29267
- };
29741
+ /**
29742
+ * @hidden
29743
+ */
29744
+ get customHintTemplate() {
29745
+ if (this.rowReorderable) {
29746
+ const allColumns = this.columnList.toArray();
29747
+ const rowReorderColumn = allColumns.find(column => column.isRowReorderColumn);
29748
+ return rowReorderColumn.rowDragHintTemplateRef;
29749
+ }
29268
29750
  }
29269
- if (filter.field && filter.value !== undefined) {
29270
- if (typeof filter.value === 'string' && isDateOperator(filter.operator)) {
29271
- const date = parseDate(filter.value);
29751
+ /**
29752
+ * @hidden
29753
+ */
29754
+ get hintContext() {
29755
+ if (this.customHintTemplate) {
29756
+ const draggedRow = this.rowReorderService?.getDraggedRow(this.flatData);
29272
29757
  return {
29273
- ...filter,
29274
- value: date || filter.value
29758
+ $implicit: draggedRow?.dataItem,
29759
+ rowIndex: draggedRow?.rowIndex
29275
29760
  };
29276
29761
  }
29277
29762
  }
29278
- return filter;
29279
- };
29280
- /**
29281
- * @hidden
29282
- */
29283
- const isDateOperator = (operator) => {
29284
- const dateOperators = [
29285
- 'eq', 'neq', 'lt', 'lte', 'gt', 'gte'
29286
- ];
29287
- return dateOperators.includes(operator);
29288
- };
29289
- /**
29290
- * @hidden
29291
- * Processes cell highlights for a specific filter and item.
29292
- */
29293
- const processCellHighlights = (filter, rowIndex, columns, highlightItems) => {
29294
- Object.keys(filter.cells).forEach((columnField) => {
29295
- const actualColumnIndex = Array.from(columns).findIndex((col) => col.field === columnField);
29296
- if (actualColumnIndex !== -1) {
29297
- highlightItems.push({
29298
- itemKey: rowIndex,
29299
- columnKey: actualColumnIndex,
29300
- });
29301
- }
29302
- });
29303
- };
29304
- /**
29305
- * @hidden
29306
- * Processes filtered results and adds highlight items.
29307
- */
29308
- const processFilteredResults = (filteredResults, data, filter, columns, highlightItems) => {
29309
- filteredResults?.forEach((item) => {
29310
- const rowIndex = data.findIndex((dataItem) => dataItem === item);
29311
- if (filter.cells && Object.keys(filter.cells).length > 0) {
29312
- processCellHighlights(filter, rowIndex, columns, highlightItems);
29763
+ /**
29764
+ * Defines the page size used by the Grid pager.
29765
+ * Required for the [`paging`]({% slug paging_grid %}) feature.
29766
+ */
29767
+ pageSize;
29768
+ /**
29769
+ * Defines the height in pixels for the Grid when `scrollable` is set.
29770
+ * You can also set the height using `style.height` with units like `px`, `%`, `em`, or `rem`.
29771
+ */
29772
+ height;
29773
+ /**
29774
+ * Sets the `style.height` attribute of each Grid data or group header/footer row (`tr`) element in the DOM in pixels.
29775
+ * If some row cells have content that requires more space, the row automatically expands to fit the content.
29776
+ */
29777
+ rowHeight;
29778
+ /**
29779
+ * Enables or disables adaptive mode. Adaptive rendering is off by default.
29780
+ *
29781
+ * @default 'none'
29782
+ */
29783
+ adaptiveMode = 'none';
29784
+ /**
29785
+ * Sets the `style.height` attribute of each Grid detail row (`tr.k-detail-row`) element in the DOM in pixels.
29786
+ * If the detail row has content that requires more space, the row automatically expands to fit the content.
29787
+ */
29788
+ detailRowHeight;
29789
+ /**
29790
+ * Defines the number of records to skip in the pager.
29791
+ * Required for the [`paging`]({% slug paging_grid %}) feature.
29792
+ */
29793
+ get skip() {
29794
+ return this._skip;
29795
+ }
29796
+ set skip(value) {
29797
+ if (typeof value === 'number' && value >= 0) {
29798
+ this._skip = this.rowReorderService.skip = value;
29313
29799
  }
29314
- else {
29315
- highlightItems.push({
29316
- itemKey: rowIndex,
29317
- });
29800
+ }
29801
+ /**
29802
+ * Defines the scroll mode for the Grid.
29803
+ *
29804
+ * @default 'scrollable'
29805
+ */
29806
+ scrollable = 'scrollable';
29807
+ /**
29808
+ * Enables the selection feature of the Grid. The `selectable` property can be set to `true`, `false`, or an object with additional settings.
29809
+ * [See example](slug:grid_row_selection).
29810
+ *
29811
+ * @default false
29812
+ */
29813
+ selectable = false;
29814
+ /**
29815
+ * Sets the descriptors for sorting the data ([see example](slug:manual_sorting_grid)).
29816
+ */
29817
+ set sort(value) {
29818
+ if (isArray(value)) {
29819
+ this._sort = value;
29318
29820
  }
29319
- });
29320
- };
29321
- /**
29322
- * @hidden
29323
- * Highlights items in a grid based on the provided filters and columns.
29324
- * @param data - The data to be highlighted.
29325
- * @param filters - The composite highlight descriptors containing the filters and logic.
29326
- * @param columns - The columns of the grid.
29327
- * @returns An array of HighlightItem objects representing the highlighted items.
29328
- */
29329
- const highlightBy = (data, filters, columns) => {
29330
- const highlightItems = [];
29331
- filters.forEach((filter) => {
29332
- const processedFilters = filter.filters.map((filter) => convertDateStringsInFilter(filter));
29333
- const filteredResults = filterBy(data, {
29334
- logic: filter.logic || "and",
29335
- filters: processedFilters,
29336
- });
29337
- processFilteredResults(filteredResults, data, filter, columns, highlightItems);
29338
- });
29339
- return highlightItems;
29340
- };
29341
-
29342
- /**
29343
- * @hidden
29344
- */
29345
- class AiAssistantComponent {
29346
- http;
29347
- ctx;
29348
- columnInfoService;
29349
- aiPrompt;
29350
- activeView = 0;
29351
- requestUrl;
29352
- requestOptions;
29353
- aiPromptSettings;
29354
- aiToolDirective;
29355
- streaming = false;
29356
- disabledGenerateButton = false;
29357
- lastMessage;
29358
- requestData;
29359
- currentRequestSubscription = null;
29360
- //Remove this when the AI Assistant has a built-in loading indicator
29361
- loadingOutput = { id: 'k-loading-item', output: '', prompt: '' };
29362
- columns = [];
29363
- idCounter = 0;
29364
- constructor(http, ctx, columnInfoService) {
29365
- this.http = http;
29366
- this.ctx = ctx;
29367
- this.columnInfoService = columnInfoService;
29368
- }
29369
- ngAfterViewInit() {
29370
- this.columns = this.columnInfoService.leafNamedColumns.map((col) => ({ field: col.field }));
29371
- }
29372
- ngOnDestroy() {
29373
- this.unsubscribeCurrentRequest();
29374
- }
29375
- message(message) {
29376
- return this.ctx.localization.get(message);
29377
- }
29378
- cancelRequest() {
29379
- this.aiToolDirective.cancelRequest.emit();
29380
- this.unsubscribeCurrentRequest();
29381
- this.streaming = false;
29382
- }
29383
- onPromptRequest(ev) {
29384
- if (this.aiToolDirective.promptOutputs.length === 0) {
29385
- this.aiToolDirective.promptOutputs.push(this.loadingOutput);
29386
- }
29387
- this.unsubscribeCurrentRequest();
29388
- this.streaming = true;
29389
- this.activeView = 1;
29390
- if (ev.prompt) {
29391
- this.lastMessage = ev.prompt;
29392
- }
29393
- this.requestData = {
29394
- columns: this.columns,
29395
- promptMessage: ev.prompt,
29396
- url: this.requestUrl,
29397
- requestOptions: {
29398
- ...this.requestOptions
29399
- }
29400
- };
29401
- if (!this.requestOptions.body) {
29402
- const requestBody = {
29403
- role: this.requestData.requestOptions.role,
29404
- contents: [
29405
- {
29406
- text: this.requestData.promptMessage
29407
- }
29408
- ],
29409
- columns: this.requestData.columns
29410
- };
29411
- this.requestData.requestOptions.body = requestBody;
29412
- }
29413
- this.aiToolDirective.promptRequest.emit({ requestData: this.requestData, isRetry: ev.isRetry });
29414
- if (!this.requestUrl) {
29415
- return;
29416
- }
29417
- this.currentRequestSubscription = this.sendPromptRequest().subscribe((res) => {
29418
- if (res.body) {
29419
- this.processResponse(res);
29420
- this.streaming = false;
29421
- }
29422
- this.currentRequestSubscription = null;
29423
- }, (error) => {
29424
- this.handleError(error);
29425
- this.streaming = false;
29426
- this.currentRequestSubscription = null;
29427
- });
29428
- }
29429
- sendPromptRequest() {
29430
- const request = new HttpRequest(this.requestData.requestOptions.method, this.requestData.url, this.requestData.requestOptions.body, this.requestData.requestOptions);
29431
- return this.http.request(request);
29432
- }
29433
- processResponse(response) {
29434
- if (this.aiToolDirective.autoClose) {
29435
- this.aiToolDirective.emitOpenClose = true;
29436
- this.aiToolDirective.toggleWindow();
29437
- }
29438
- const responseBody = response.body;
29439
- const responseSuccessEvent = new GridToolbarAIResponseSuccessEvent(response);
29440
- this.aiToolDirective.responseSuccess.emit(responseSuccessEvent);
29441
- if (responseSuccessEvent.isDefaultPrevented()) {
29442
- this.deleteLoadingOutput();
29443
- return;
29444
- }
29445
- const isFilterable = Boolean(this.ctx.grid.filterable);
29446
- const isSortable = Boolean(this.ctx.grid.sortable);
29447
- const isGroupable = Boolean(this.ctx.grid.groupable);
29448
- if (isFilterable && responseBody.filter) {
29449
- this.processFilterResponse(responseBody.filter);
29450
- }
29451
- if (isSortable && responseBody.sort) {
29452
- this.processArrayResponse(responseBody.sort, this.ctx.grid.currentState.sort || [], (item) => item.field, (mergedArray) => this.ctx.grid.sortChange.next(mergedArray));
29453
- }
29454
- if (isGroupable && responseBody.group) {
29455
- this.processArrayResponse(responseBody.group, this.ctx.grid.currentState.group || [], (item) => item.field, (mergedArray) => this.ctx.grid.groupChange.next(mergedArray));
29456
- }
29457
- if (this.ctx.highlightDirective && responseBody.highlight) {
29458
- this.processHighlightResponse(responseBody.highlight);
29459
- }
29460
- const responseContentStart = [`${this.ctx.localization.get('aiAssistantOutputCardBodyContent')} \n`];
29461
- const responseContentBody = responseBody.messages
29462
- .map((output, idx) => `${idx + 1} ${output}`)
29463
- .join('\n');
29464
- const output = {
29465
- id: this.idCounter++,
29466
- title: this.ctx.localization.get('aiAssistantOutputCardTitle'),
29467
- prompt: this.lastMessage,
29468
- output: responseContentStart.concat(responseContentBody).join(''),
29469
- };
29470
- this.deleteLoadingOutput();
29471
- this.aiToolDirective.promptOutputs.unshift(output);
29472
- }
29473
- handleError(error) {
29474
- const responseErrorEvent = new GridToolbarAIResponseErrorEvent(error);
29475
- this.aiToolDirective.responseError.emit(responseErrorEvent);
29476
- if (responseErrorEvent.isDefaultPrevented()) {
29477
- this.deleteLoadingOutput();
29478
- return;
29479
- }
29480
- const output = {
29481
- id: this.idCounter++,
29482
- prompt: this.lastMessage,
29483
- output: error.message
29484
- };
29485
- this.deleteLoadingOutput();
29486
- this.aiToolDirective.promptOutputs.unshift(output);
29487
29821
  }
29488
- deleteLoadingOutput() {
29489
- if (this.aiToolDirective.promptOutputs[0]?.id === this.loadingOutput.id) {
29490
- this.aiToolDirective.promptOutputs.splice(0, 1);
29491
- }
29822
+ get sort() {
29823
+ return this._sort;
29492
29824
  }
29493
- unsubscribeCurrentRequest() {
29494
- if (this.currentRequestSubscription) {
29495
- this.currentRequestSubscription.unsubscribe();
29496
- this.currentRequestSubscription = null;
29825
+ /**
29826
+ * Specifies the sizing for Grid elements like tables, buttons, and inputs.
29827
+ *
29828
+ * @default 'medium'
29829
+ */
29830
+ set size(size) {
29831
+ this._size = size;
29832
+ if (size === 'none') {
29833
+ this.wrapper.nativeElement.classList.remove('k-grid-sm', 'k-grid-md');
29497
29834
  }
29835
+ this.sizingService.changes.next(this.size);
29498
29836
  }
29499
- processArrayResponse(newItems, currentItems, getField, updateGrid) {
29500
- if (newItems?.length === 0) {
29501
- updateGrid([]);
29502
- }
29503
- else if (newItems?.length) {
29504
- let mergedArray = [...newItems];
29505
- const newFields = newItems.map(getField);
29506
- const existingItemsToKeep = currentItems.filter(item => !newFields.includes(getField(item)));
29507
- mergedArray = [...mergedArray, ...existingItemsToKeep];
29508
- updateGrid(mergedArray);
29509
- }
29837
+ get size() {
29838
+ return this._size;
29510
29839
  }
29511
- processHighlightResponse(highlight) {
29512
- if (highlight.length === 0) {
29513
- this.ctx.highlightDirective['setState']([]);
29514
- return;
29840
+ /**
29841
+ * A function that defines how to track changes for the data rows.
29842
+ * By default, the Grid tracks changes by the index of the data item.
29843
+ * Edited rows are tracked by reference.
29844
+ * [See example](slug:track_changes_grid).
29845
+ */
29846
+ trackBy = defaultTrackBy;
29847
+ /**
29848
+ * Sets the filter descriptor for the data ([see examples](slug:manual_filtering_grid)).
29849
+ */
29850
+ filter;
29851
+ /**
29852
+ * Sets the descriptors for grouping the data ([see example](slug:manual_grouping_grid)).
29853
+ */
29854
+ set group(value) {
29855
+ if (isArray(value)) {
29856
+ this._group = value;
29515
29857
  }
29516
- const highlightedItems = highlightBy(this.ctx.dataBindingDirective['originalData'], highlight, this.columns);
29517
- this.ctx.highlightDirective['setState'](highlightedItems);
29518
29858
  }
29519
- processFilterResponse(filter) {
29520
- const processedFilter = convertDateStringsInFilter(filter);
29521
- const clearFilter = Object.keys(processedFilter).length === 0;
29522
- if (clearFilter) {
29523
- this.ctx.grid.filterChange.next(undefined);
29524
- }
29525
- else if (processedFilter?.filters.length) {
29526
- const currentFilter = this.ctx.grid.currentState.filter;
29527
- let mergedFilter = processedFilter;
29528
- if (currentFilter && currentFilter.filters?.length > 0) {
29529
- mergedFilter = {
29530
- logic: 'and',
29531
- filters: [
29532
- currentFilter,
29533
- processedFilter
29534
- ]
29535
- };
29536
- }
29537
- this.ctx.grid.filterChange.next(mergedFilter);
29538
- }
29859
+ get group() {
29860
+ return this._group;
29539
29861
  }
29540
- 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 });
29541
- 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: `
29542
- <kendo-aiprompt
29543
- #aiPrompt
29544
- [promptSuggestions]="aiPromptSettings?.promptSuggestions"
29545
- [showOutputRating]="aiPromptSettings?.showOutputRating"
29546
- [streaming]="streaming"
29547
- [speechToTextButton]="aiPromptSettings?.speechToTextButton"
29548
- [(activeView)]="activeView"
29549
- [generateButtonSVGIcon]="aiPromptSettings?.generateButtonSVGIcon"
29550
- [generateButtonIcon]="aiPromptSettings?.generateButtonIcon"
29551
- [disabledGenerateButton]="disabledGenerateButton || promptView.textAreaValue?.length === 0"
29552
- [promptOutputs]="aiPromptSettings?.promptOutputs"
29553
- [textAreaSettings]="aiPromptSettings?.textAreaSettings"
29554
- (promptRequest)="onPromptRequest($event)"
29555
- (promptRequestCancel)="cancelRequest()"
29556
- >
29557
- <kendo-aiprompt-prompt-view #promptView></kendo-aiprompt-prompt-view>
29558
- <kendo-aiprompt-output-view></kendo-aiprompt-output-view>
29559
- <ng-template *ngIf="streaming && aiPrompt.streaming" kendoAIPromptOutputTemplate let-output>
29560
- <div class="k-card">
29561
- <div class="k-card-header">
29562
- <div class="k-card-title">
29563
- <span class="k-skeleton k-skeleton-text k-skeleton-pulse" [style.width.px]="200"></span>
29564
- </div>
29565
- <div class="k-card-subtitle">
29566
- <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
29567
- </div>
29568
- </div>
29569
- <div class="k-card-body">
29570
- <span class="k-skeleton k-skeleton-rect k-skeleton-pulse" style="height: 80px;"></span>
29571
- </div>
29572
- <div class="k-card-actions">
29573
- <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
29574
- </div>
29575
- </div>
29576
- </ng-template>
29577
- <ng-template *ngIf="!(streaming && aiPrompt.streaming)" kendoAIPromptOutputBodyTemplate let-output>
29578
- <p>{{output.output}}</p>
29579
- </ng-template>
29580
- <kendo-aiprompt-messages
29581
- [generateOutput]="message('aiAssistantApplyButtonText')"
29582
- ></kendo-aiprompt-messages>
29583
- </kendo-aiprompt>
29584
- `, 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]" }] });
29585
- }
29586
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AiAssistantComponent, decorators: [{
29587
- type: Component,
29588
- args: [{
29589
- standalone: true,
29590
- imports: [NgIf, AIPromptComponent, AIPromptCustomMessagesComponent, PromptViewComponent, OutputViewComponent, AIPromptOutputTemplateDirective, AIPromptOutputBodyTemplateDirective],
29591
- template: `
29592
- <kendo-aiprompt
29593
- #aiPrompt
29594
- [promptSuggestions]="aiPromptSettings?.promptSuggestions"
29595
- [showOutputRating]="aiPromptSettings?.showOutputRating"
29596
- [streaming]="streaming"
29597
- [speechToTextButton]="aiPromptSettings?.speechToTextButton"
29598
- [(activeView)]="activeView"
29599
- [generateButtonSVGIcon]="aiPromptSettings?.generateButtonSVGIcon"
29600
- [generateButtonIcon]="aiPromptSettings?.generateButtonIcon"
29601
- [disabledGenerateButton]="disabledGenerateButton || promptView.textAreaValue?.length === 0"
29602
- [promptOutputs]="aiPromptSettings?.promptOutputs"
29603
- [textAreaSettings]="aiPromptSettings?.textAreaSettings"
29604
- (promptRequest)="onPromptRequest($event)"
29605
- (promptRequestCancel)="cancelRequest()"
29606
- >
29607
- <kendo-aiprompt-prompt-view #promptView></kendo-aiprompt-prompt-view>
29608
- <kendo-aiprompt-output-view></kendo-aiprompt-output-view>
29609
- <ng-template *ngIf="streaming && aiPrompt.streaming" kendoAIPromptOutputTemplate let-output>
29610
- <div class="k-card">
29611
- <div class="k-card-header">
29612
- <div class="k-card-title">
29613
- <span class="k-skeleton k-skeleton-text k-skeleton-pulse" [style.width.px]="200"></span>
29614
- </div>
29615
- <div class="k-card-subtitle">
29616
- <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
29617
- </div>
29618
- </div>
29619
- <div class="k-card-body">
29620
- <span class="k-skeleton k-skeleton-rect k-skeleton-pulse" style="height: 80px;"></span>
29621
- </div>
29622
- <div class="k-card-actions">
29623
- <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
29624
- </div>
29625
- </div>
29626
- </ng-template>
29627
- <ng-template *ngIf="!(streaming && aiPrompt.streaming)" kendoAIPromptOutputBodyTemplate let-output>
29628
- <p>{{output.output}}</p>
29629
- </ng-template>
29630
- <kendo-aiprompt-messages
29631
- [generateOutput]="message('aiAssistantApplyButtonText')"
29632
- ></kendo-aiprompt-messages>
29633
- </kendo-aiprompt>
29634
- `
29635
- }]
29636
- }], ctorParameters: function () { return [{ type: i1$8.HttpClient }, { type: ContextService }, { type: ColumnInfoService }]; }, propDecorators: { aiPrompt: [{
29637
- type: ViewChild,
29638
- args: [AIPromptComponent]
29639
- }] } });
29640
-
29641
- /**
29642
- * Represents an AI Assistant tool of the Grid.
29643
- * Use this directive on any `kendo-toolbar-button` inside a ToolbarComponent in the Grid.
29644
- *
29645
- * @example
29646
- * ```html-no-run
29647
- * <kendo-grid>
29648
- * <kendo-toolbar>
29649
- * <kendo-toolbar-button kendoGridAIAssistantTool></kendo-toolbar-button>
29650
- * </kendo-toolbar>
29651
- * </kendo-grid>
29652
- * ```
29653
- * @remarks
29654
- * Applied to: {@link ToolBarButtonComponent}.
29655
- */
29656
- class AIAssistantToolbarDirective extends ToolbarToolBase {
29657
- windowService;
29658
- host;
29659
- ctx;
29660
- zone;
29661
- refresh;
29662
- /**
29663
- * The URL to which the AI Assistant tool sends the AI request.
29664
- * - 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.
29665
- * - 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.
29666
- */
29667
- requestUrl;
29668
29862
  /**
29669
- * Configures the request options that the AI Assistant tool sends with the AI request.
29863
+ * If `true`, renders only columns in the current viewport.
29670
29864
  *
29671
- * @default { headers: new HttpHeaders({ 'Content-Type': 'application/json' }), role: 'user', method: 'POST', responseType: 'json', withCredentials: false }
29865
+ * @default false
29672
29866
  */
29673
- requestOptions;
29867
+ virtualColumns = false;
29674
29868
  /**
29675
- * Configures the initial settings for the AI Assistant Window when opened.
29869
+ * @hidden
29676
29870
  */
29677
- aiWindowSettings;
29871
+ get showStatusBar() {
29872
+ return !!(this.selectable);
29873
+ }
29678
29874
  /**
29679
- * Configures the initial settings for the AI Prompt component that the AI Assistant Window component uses when opened.
29875
+ * @hidden
29680
29876
  */
29681
- aiPromptSettings;
29877
+ get showTopToolbar() {
29878
+ return this.toolbarTemplate && ['top', 'both'].indexOf(this.toolbarTemplate.position) > -1;
29879
+ }
29682
29880
  /**
29683
- * Determines whether to close the AI Assistant Window automatically after a successful request.
29684
- * @default true
29881
+ * @hidden
29685
29882
  */
29686
- autoClose = true;
29883
+ get showBottomToolbar() {
29884
+ return this.toolbarTemplate && ['bottom', 'both'].indexOf(this.toolbarTemplate.position) > -1;
29885
+ }
29687
29886
  /**
29688
- * Determines whether to keep the AI Prompt's outputs after closing the AI Assistant Window.
29689
- * @default false
29887
+ * @hidden
29690
29888
  */
29691
- keepOutputHistory = false;
29889
+ get isLocked() {
29890
+ return (this.lockedLeafColumns.length > 0 && !this.isStacked);
29891
+ }
29692
29892
  /**
29693
- * Emits an event before the AI Assistant tool sends the AI request.
29694
- * - When you provide a `requestUrl`, you can handle the event to modify the request options.
29695
- * - When you do not provide a `requestUrl`, you can handle the event to perform an entirely custom request.
29893
+ * @hidden
29696
29894
  */
29697
- promptRequest = new EventEmitter();
29895
+ get showTopPager() {
29896
+ const position = this.pageable.position;
29897
+ return this.pageable !== false && ['top', 'both'].indexOf(position) > -1;
29898
+ }
29698
29899
  /**
29699
- * Emits an event when the user clicks the cancel button.
29900
+ * @hidden
29700
29901
  */
29701
- cancelRequest = new EventEmitter();
29902
+ get showBottomPager() {
29903
+ const position = this.pageable.position;
29904
+ return this.pageable !== false && position !== 'top';
29905
+ }
29702
29906
  /**
29703
- * Emits an event when the AI Assistant tool completes the AI request successfully.
29704
- * The event contains the response from the AI service and is preventable to allow stopping the default response handling.
29907
+ * @hidden
29705
29908
  */
29706
- responseSuccess = new EventEmitter();
29909
+ get hasPager() {
29910
+ return this.showTopPager || this.showBottomPager;
29911
+ }
29707
29912
  /**
29708
- * Emits an event when the AI Assistant tool completes the AI request with an error.
29709
- * The event contains the error response from the AI service and is preventable to allow stopping the default error handling.
29913
+ * @hidden
29710
29914
  */
29711
- responseError = new EventEmitter();
29915
+ get showGroupPanel() {
29916
+ const isGroupable = this.groupable && this.groupable.enabled !== false;
29917
+ const isGrouped = this.group?.length > 0;
29918
+ return this.isStacked ? isGroupable && isGrouped : isGroupable;
29919
+ }
29712
29920
  /**
29713
- * Emits an event when the AI Assistant tool closes.
29921
+ * @hidden
29714
29922
  */
29715
- close = new EventEmitter();
29923
+ get groupableEmptyText() {
29924
+ return this.groupable.emptyText;
29925
+ }
29716
29926
  /**
29717
- * Emits an event when the AI Assistant tool opens.
29927
+ * @hidden
29718
29928
  */
29719
- open = new EventEmitter();
29720
- tableWizardIcon = tableWizardIcon;
29721
- emitOpenClose = false;
29722
- promptOutputs = [];
29723
- windowRef;
29724
- subs = new Subscription();
29725
- defaultAiPromptSettings = {
29726
- speechToTextButton: true,
29727
- generateButtonSVGIcon: this.tableWizardIcon,
29728
- generateButtonIcon: 'table-wizard'
29729
- };
29730
- constructor(windowService, host, ctx, zone, refresh, cdr) {
29731
- super(host, ToolbarToolName.aiAssistant, ctx, zone, cdr);
29732
- this.windowService = windowService;
29733
- this.host = host;
29734
- this.ctx = ctx;
29735
- this.zone = zone;
29736
- this.refresh = refresh;
29737
- this.host.rounded = 'full';
29738
- this.host.themeColor = 'primary';
29739
- this.host.showText = 'never';
29740
- }
29741
- ngOnInit() {
29742
- this.subs.add(this.host.click.subscribe(() => this.onClick()));
29743
- const hasToolbarIcon = isPresent$1(this.host.toolbarOptions.icon) && this.host.toolbarOptions.icon !== '';
29744
- const hasOverflowIcon = isPresent$1(this.host.overflowOptions.icon) && this.host.overflowOptions.icon !== '';
29745
- const hasIcon = hasToolbarIcon && hasOverflowIcon;
29746
- const hasSvgIcon = isPresent$1(this.host.toolbarOptions.svgIcon) && isPresent$1(this.host.overflowOptions.svgIcon);
29747
- if (!hasIcon) {
29748
- this.host.icon = 'sparkles';
29749
- }
29750
- if (!hasSvgIcon) {
29751
- this.host.svgIcon = sparklesIcon;
29752
- }
29753
- this.requestOptions = { ...DEFAULT_AI_REQUEST_OPTIONS, ...this.requestOptions };
29929
+ get marqueeSelection() {
29930
+ return this.selectionService.enableMarquee || this.cellSelectionService.enableMarquee;
29754
29931
  }
29755
- ngAfterViewInit() {
29756
- super.ngAfterViewInit();
29757
- this.zone.onStable.pipe(take(1)).subscribe(() => {
29758
- this.buttonElement?.setAttribute('aria-haspopup', 'dialog');
29759
- this.buttonElement?.setAttribute('aria-expanded', 'false');
29760
- const needsTitle = this.host.showText !== 'always' && this.host.showText !== 'toolbar';
29761
- if (needsTitle && !this.host.title) {
29762
- this.buttonElement?.setAttribute('title', this.ctx.localization.get('aiAssistantToolbarToolText'));
29763
- }
29764
- });
29765
- this.subs.add(this.refresh.onRefresh.pipe(filter((tool) => tool === this.host)).subscribe((tool) => {
29766
- if (tool.overflows && this.windowRef) {
29767
- this.windowRef.close();
29768
- }
29769
- }));
29932
+ /**
29933
+ * @hidden
29934
+ */
29935
+ get isAdaptiveModeEnabled() {
29936
+ return this.adaptiveMode === 'auto';
29770
29937
  }
29771
- ngOnDestroy() {
29772
- super.ngOnDestroy();
29773
- this.subs.unsubscribe();
29774
- this.promptOutputs = [];
29938
+ /**
29939
+ * @hidden
29940
+ *
29941
+ * The `isOpen` property is used to determine if a Grid Popup or ActionSheet is open.
29942
+ */
29943
+ get isOpen() {
29944
+ return isPresent(this.adaptiveGridService.popupRef) || this.isActionSheetExpanded;
29775
29945
  }
29776
29946
  /**
29777
29947
  * @hidden
29778
29948
  */
29779
- onClick() {
29780
- this.emitOpenClose = true;
29781
- this.toggleWindow();
29949
+ get isActionSheetExpanded() {
29950
+ return Boolean(this.adaptiveRenderer?.actionSheet?.expanded);
29782
29951
  }
29783
29952
  /**
29784
- * Toggles the AI Assistant window.
29785
- */
29786
- toggleWindow() {
29787
- if (!this.windowRef) {
29788
- this.openWindow();
29789
- }
29790
- else {
29791
- this.closeWindow();
29792
- }
29793
- }
29794
- openWindow() {
29795
- if (!this.keepOutputHistory) {
29796
- this.promptOutputs = [];
29797
- }
29798
- const defaultWindowWidth = 437;
29799
- const rtl = this.ctx.localization.rtl;
29800
- const defaultWindowSettings = {
29801
- left: rtl ? this.buttonElement.offsetLeft - (this.aiWindowSettings.width || defaultWindowWidth) : this.buttonElement.offsetLeft + this.buttonElement.offsetWidth,
29802
- top: this.buttonElement.offsetTop + this.buttonElement.offsetHeight,
29803
- width: defaultWindowWidth,
29804
- title: this.ctx.localization.get('aiAssistantWindowTitle'),
29805
- cssClass: 'k-grid-assistant-window',
29806
- content: AiAssistantComponent,
29807
- autoFocusedElement: '.k-input-inner',
29808
- appendTo: this.ctx.grid.windowContainer
29809
- };
29810
- this.aiWindowSettings = {
29811
- ...defaultWindowSettings,
29812
- ...this.aiWindowSettings
29813
- };
29814
- this.windowRef = this.windowService.open(this.aiWindowSettings);
29815
- this.windowRef.window.instance.messages = {
29816
- closeTitle: this.ctx.localization.get('aiAssistantWindowCloseTitle'),
29817
- maximizeTitle: this.ctx.localization.get('aiAssistantWindowMaximizeTitle'),
29818
- minimizeTitle: this.ctx.localization.get('aiAssistantWindowMinimizeTitle'),
29819
- restoreTitle: this.ctx.localization.get('aiAssistantWindowRestoreTitle')
29820
- };
29821
- const aiPrompt = this.windowRef.content.instance;
29822
- aiPrompt.requestUrl = this.requestUrl;
29823
- aiPrompt.requestOptions = this.requestOptions;
29824
- aiPrompt.aiToolDirective = this;
29825
- aiPrompt.disabledGenerateButton = this.aiPromptSettings?.disabledGenerateButton;
29826
- aiPrompt.streaming = this.aiPromptSettings?.streaming || false;
29827
- aiPrompt.activeView = this.aiPromptSettings?.activeView || 0;
29828
- aiPrompt.aiPromptSettings = { ...this.defaultAiPromptSettings, ...this.aiPromptSettings };
29829
- if (!aiPrompt.aiPromptSettings.promptOutputs) {
29830
- aiPrompt.aiPromptSettings.promptOutputs = this.promptOutputs;
29831
- }
29832
- if (this.emitOpenClose) {
29833
- this.zone.onStable.pipe(take(1)).subscribe(() => {
29834
- const event = {
29835
- aiWindow: this.windowRef.window.instance,
29836
- aiPrompt: this.windowRef.content.instance.aiPrompt
29837
- };
29838
- this.open.emit(event);
29839
- this.emitOpenClose = false;
29840
- });
29841
- }
29842
- this.subs.add(this.windowRef.window.instance.close.subscribe(() => {
29843
- this.emitOpenClose = true;
29844
- this.closeWindow(true);
29845
- }));
29846
- this.host.selected = true;
29847
- }
29848
- closeWindow(focusAnchor = false) {
29849
- this.windowRef.close();
29850
- if (this.emitOpenClose) {
29851
- this.close.emit();
29852
- this.emitOpenClose = false;
29853
- }
29854
- this.windowRef = null;
29855
- this.buttonElement?.setAttribute('aria-expanded', 'false');
29856
- this.buttonElement?.removeAttribute('aria-controls');
29857
- this.host.selected = false;
29858
- focusAnchor && this.buttonElement?.focus();
29859
- }
29860
- 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 });
29861
- 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 });
29862
- }
29863
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIAssistantToolbarDirective, decorators: [{
29864
- type: Directive,
29865
- args: [{
29866
- selector: '[kendoGridAIAssistantTool]',
29867
- standalone: true
29868
- }]
29869
- }], ctorParameters: function () { return [{ type: i1$7.WindowService }, { type: i54.ToolBarButtonComponent }, { type: ContextService }, { type: i0.NgZone }, { type: i54.RefreshService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { requestUrl: [{
29870
- type: Input
29871
- }], requestOptions: [{
29872
- type: Input
29873
- }], aiWindowSettings: [{
29874
- type: Input
29875
- }], aiPromptSettings: [{
29876
- type: Input
29877
- }], autoClose: [{
29878
- type: Input
29879
- }], keepOutputHistory: [{
29880
- type: Input
29881
- }], promptRequest: [{
29882
- type: Output
29883
- }], cancelRequest: [{
29884
- type: Output
29885
- }], responseSuccess: [{
29886
- type: Output
29887
- }], responseError: [{
29888
- type: Output
29889
- }], close: [{
29890
- type: Output
29891
- }], open: [{
29892
- type: Output
29893
- }] } });
29894
-
29895
- const createControl = (source) => (acc, key) => {
29896
- acc[key] = new FormControl(source[key]);
29897
- return acc;
29898
- };
29899
- const validateColumnsField = (columns) => expandColumns(columns.toArray())
29900
- .filter(isColumnComponent)
29901
- .filter(({ field }) => !isValidFieldName(field))
29902
- .forEach(({ field }) => console.warn(ColumnConfigurationErrorMessages.fieldName(field)));
29903
- const handleExpandCollapseGroupsService = (service, expandEmitter, collapseEmitter, map) => (service.changes.pipe(filter(({ group, emit }) => emit && isPresent(group)))
29904
- .subscribe((x) => x.expand ? expandEmitter.emit(map(x)) : collapseEmitter.emit(map(x))));
29905
- const handleExpandCollapseDetailsService = (service, expandEmitter, collapseEmitter, map) => (service.changes.pipe(filter(({ dataItem }) => isPresent(dataItem)))
29906
- .subscribe((x) => x.expand ? expandEmitter.emit(map(x)) : collapseEmitter.emit(map(x))));
29907
- const isInEditedCell = (element, gridElement, isStacked = false) => (closest(element, matchesClasses('k-grid-edit-cell')) || (isStacked && closest(element, matchesClasses('k-grid-stack-edit-cell')))) &&
29908
- closest(element, matchesNodeName('kendo-grid')) === gridElement;
29909
- const NOTIFY_DELAY = 500;
29910
- /**
29911
- * Represents the Kendo UI for Angular Data Grid component.
29912
- *
29913
- * Use the `kendo-grid` component to display and manage tabular data.
29914
- *
29915
- * @example
29916
- * ```html
29917
- * <kendo-grid [data]="gridData"></kendo-grid>
29918
- * ```
29919
- *
29920
- * @remarks
29921
- * Supported children components are:
29922
- * {@link CheckboxColumnComponent},
29923
- * {@link ColumnChooserComponent},
29924
- * {@link ColumnComponent},
29925
- * {@link ColumnGroupComponent},
29926
- * {@link ColumnMenuAutoSizeAllColumnsComponent},
29927
- * {@link ColumnMenuAutoSizeColumnComponent},
29928
- * {@link ColumnMenuChooserComponent},
29929
- * {@link ColumnMenuComponent},
29930
- * {@link ColumnMenuFilterComponent},
29931
- * {@link ColumnMenuItemComponent},
29932
- * {@link ColumnMenuLockComponent},
29933
- * {@link ColumnMenuPositionComponent},
29934
- * {@link ColumnMenuSortComponent},
29935
- * {@link ColumnMenuStickComponent},
29936
- * {@link CommandColumnComponent},
29937
- * {@link CustomMessagesComponent},
29938
- * {@link ExcelComponent},
29939
- * {@link GridSpacerComponent},
29940
- * {@link PDFComponent},
29941
- * {@link RowReorderColumnComponent},
29942
- * {@link SpanColumnComponent},
29943
- * {@link ToolBarComponent}.
29944
- */
29945
- class GridComponent {
29946
- supportService;
29947
- selectionService;
29948
- cellSelectionService;
29949
- wrapper;
29950
- groupInfoService;
29951
- groupsService;
29952
- changeNotification;
29953
- detailsService;
29954
- editService;
29955
- filterService;
29956
- pdfService;
29957
- responsiveService;
29958
- renderer;
29959
- excelService;
29960
- ngZone;
29961
- scrollSyncService;
29962
- domEvents;
29963
- columnResizingService;
29964
- changeDetectorRef;
29965
- columnReorderService;
29966
- columnInfoService;
29967
- navigationService;
29968
- sortService;
29969
- scrollRequestService;
29970
- localization;
29971
- ctx;
29972
- sizingService;
29973
- adaptiveGridService;
29974
- rowReorderService;
29975
- dataMappingService;
29976
- /**
29977
- * Sets the data of the Grid. If you provide an array, the Grid gets the total count automatically.
29978
- * ([more information and example]({% slug binding_grid %})).
29979
- */
29980
- set data(value) {
29981
- this._data = value;
29982
- if (this.selectable && this.selectableSettings?.enabled && this.isVirtual) {
29983
- this.blockArrowSelection = false;
29984
- }
29985
- if (this.notifyTimeout) {
29986
- clearTimeout(this.notifyTimeout);
29987
- this.notifyTimeout = null;
29988
- }
29989
- if (this.rowReorderable) {
29990
- this.ngZone.runOutsideAngular(() => {
29991
- this.notifyTimeout = setTimeout(() => {
29992
- this.notifyReorderContainers();
29993
- }, NOTIFY_DELAY);
29994
- });
29995
- }
29996
- }
29997
- get data() {
29998
- return this._data;
29999
- }
30000
- get hintText() {
30001
- return this.rowReorderService.getDefaultHintText(this.columnList, this.flatData);
30002
- }
30003
- /**
30004
- * @hidden
30005
- */
30006
- get customHintTemplate() {
30007
- if (this.rowReorderable) {
30008
- const allColumns = this.columnList.toArray();
30009
- const rowReorderColumn = allColumns.find(column => column.isRowReorderColumn);
30010
- return rowReorderColumn.rowDragHintTemplateRef;
30011
- }
30012
- }
30013
- /**
30014
- * @hidden
30015
- */
30016
- get hintContext() {
30017
- if (this.customHintTemplate) {
30018
- const draggedRow = this.rowReorderService?.getDraggedRow(this.flatData);
30019
- return {
30020
- $implicit: draggedRow?.dataItem,
30021
- rowIndex: draggedRow?.rowIndex
30022
- };
30023
- }
30024
- }
30025
- /**
30026
- * Defines the page size used by the Grid pager.
30027
- * Required for the [`paging`]({% slug paging_grid %}) feature.
30028
- */
30029
- pageSize;
30030
- /**
30031
- * Defines the height in pixels for the Grid when `scrollable` is set.
30032
- * You can also set the height using `style.height` with units like `px`, `%`, `em`, or `rem`.
30033
- */
30034
- height;
30035
- /**
30036
- * Sets the `style.height` attribute of each Grid data or group header/footer row (`tr`) element in the DOM in pixels.
30037
- * If some row cells have content that requires more space, the row automatically expands to fit the content.
30038
- */
30039
- rowHeight;
30040
- /**
30041
- * Enables or disables adaptive mode. Adaptive rendering is off by default.
30042
- *
30043
- * @default 'none'
30044
- */
30045
- adaptiveMode = 'none';
30046
- /**
30047
- * Sets the `style.height` attribute of each Grid detail row (`tr.k-detail-row`) element in the DOM in pixels.
30048
- * If the detail row has content that requires more space, the row automatically expands to fit the content.
30049
- */
30050
- detailRowHeight;
30051
- /**
30052
- * Defines the number of records to skip in the pager.
30053
- * Required for the [`paging`]({% slug paging_grid %}) feature.
30054
- */
30055
- get skip() {
30056
- return this._skip;
30057
- }
30058
- set skip(value) {
30059
- if (typeof value === 'number' && value >= 0) {
30060
- this._skip = this.rowReorderService.skip = value;
30061
- }
30062
- }
30063
- /**
30064
- * Defines the scroll mode for the Grid.
30065
- *
30066
- * @default 'scrollable'
30067
- */
30068
- scrollable = 'scrollable';
30069
- /**
30070
- * Enables the selection feature of the Grid. The `selectable` property can be set to `true`, `false`, or an object with additional settings.
30071
- * [See example](slug:grid_row_selection).
30072
- *
30073
- * @default false
30074
- */
30075
- selectable = false;
30076
- /**
30077
- * Sets the descriptors for sorting the data ([see example]({% slug sorting_grid %})).
30078
- */
30079
- set sort(value) {
30080
- if (isArray(value)) {
30081
- this._sort = value;
30082
- }
30083
- }
30084
- get sort() {
30085
- return this._sort;
30086
- }
30087
- /**
30088
- * Specifies the sizing for Grid elements like tables, buttons, and inputs.
30089
- *
30090
- * @default 'medium'
30091
- */
30092
- set size(size) {
30093
- this._size = size;
30094
- if (size === 'none') {
30095
- this.wrapper.nativeElement.classList.remove('k-grid-sm', 'k-grid-md');
30096
- }
30097
- this.sizingService.changes.next(this.size);
30098
- }
30099
- get size() {
30100
- return this._size;
30101
- }
30102
- /**
30103
- * A function that defines how to track changes for the data rows.
30104
- * By default, the Grid tracks changes by the index of the data item.
30105
- * Edited rows are tracked by reference.
30106
- * [See example](slug:track_changes_grid).
30107
- */
30108
- trackBy = defaultTrackBy;
30109
- /**
30110
- * Sets the filter descriptor for the data ([see examples]({% slug filtering_grid %})).
30111
- */
30112
- filter;
30113
- /**
30114
- * Sets the descriptors for grouping the data ([see example]({% slug grouping_grid %})).
30115
- */
30116
- set group(value) {
30117
- if (isArray(value)) {
30118
- this._group = value;
30119
- }
30120
- }
30121
- get group() {
30122
- return this._group;
30123
- }
30124
- /**
30125
- * If `true`, renders only columns in the current viewport.
30126
- *
30127
- * @default false
30128
- */
30129
- virtualColumns = false;
30130
- /**
30131
- * @hidden
30132
- */
30133
- get showStatusBar() {
30134
- return !!(this.selectable);
30135
- }
30136
- /**
30137
- * @hidden
30138
- */
30139
- get showTopToolbar() {
30140
- return this.toolbarTemplate && ['top', 'both'].indexOf(this.toolbarTemplate.position) > -1;
30141
- }
30142
- /**
30143
- * @hidden
30144
- */
30145
- get showBottomToolbar() {
30146
- return this.toolbarTemplate && ['bottom', 'both'].indexOf(this.toolbarTemplate.position) > -1;
30147
- }
30148
- /**
30149
- * @hidden
30150
- */
30151
- get isLocked() {
30152
- return (this.lockedLeafColumns.length > 0 && !this.isStacked);
30153
- }
30154
- /**
30155
- * @hidden
30156
- */
30157
- get showTopPager() {
30158
- const position = this.pageable.position;
30159
- return this.pageable !== false && ['top', 'both'].indexOf(position) > -1;
30160
- }
30161
- /**
30162
- * @hidden
30163
- */
30164
- get showBottomPager() {
30165
- const position = this.pageable.position;
30166
- return this.pageable !== false && position !== 'top';
30167
- }
30168
- /**
30169
- * @hidden
30170
- */
30171
- get hasPager() {
30172
- return this.showTopPager || this.showBottomPager;
30173
- }
30174
- /**
30175
- * @hidden
30176
- */
30177
- get showGroupPanel() {
30178
- const isGroupable = this.groupable && this.groupable.enabled !== false;
30179
- const isGrouped = this.group?.length > 0;
30180
- return this.isStacked ? isGroupable && isGrouped : isGroupable;
30181
- }
30182
- /**
30183
- * @hidden
30184
- */
30185
- get groupableEmptyText() {
30186
- return this.groupable.emptyText;
30187
- }
30188
- /**
30189
- * @hidden
30190
- */
30191
- get marqueeSelection() {
30192
- return this.selectionService.enableMarquee || this.cellSelectionService.enableMarquee;
30193
- }
30194
- /**
30195
- * @hidden
30196
- */
30197
- get isAdaptiveModeEnabled() {
30198
- return this.adaptiveMode === 'auto';
30199
- }
30200
- /**
30201
- * @hidden
30202
- *
30203
- * The `isOpen` property is used to determine if a Grid Popup or ActionSheet is open.
30204
- */
30205
- get isOpen() {
30206
- return isPresent(this.adaptiveGridService.popupRef) || this.isActionSheetExpanded;
30207
- }
30208
- /**
30209
- * @hidden
30210
- */
30211
- get isActionSheetExpanded() {
30212
- return Boolean(this.adaptiveRenderer?.actionSheet?.expanded);
30213
- }
30214
- /**
30215
- * @hidden
29953
+ * @hidden
30216
29954
  */
30217
29955
  gridData = () => { return this.flatData; };
30218
29956
  /**
@@ -30686,7 +30424,6 @@ class GridComponent {
30686
30424
  this._customToolbarTemplate = customToolbarTemplate;
30687
30425
  }
30688
30426
  columnMenuTemplates;
30689
- aiAssistantToolbarTool;
30690
30427
  lockedHeader;
30691
30428
  header;
30692
30429
  footer = new QueryList();
@@ -32256,7 +31993,7 @@ class GridComponent {
32256
31993
  ColumnMenuService,
32257
31994
  MenuTabbingService,
32258
31995
  DataMappingService
32259
- ], 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: `
31996
+ ], 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: `
32260
31997
  <ng-container kendoGridLocalizedMessages
32261
31998
  i18n-groupPanelEmpty="kendo.grid.groupPanelEmpty|The label visible in the Grid group panel when it is empty"
32262
31999
  groupPanelEmpty="Drag a column header and drop it here to group by that column"
@@ -32632,6 +32369,15 @@ class GridComponent {
32632
32369
 
32633
32370
  i18n-columnChooserSelectedColumnsCount="kendo.grid.columnChooserSelectedColumnsCount|The text displayed in the Column Chooser for the number of selected columns"
32634
32371
  columnChooserSelectedColumnsCount="{{ '{selectedColumnsCount} Selected items' }}"
32372
+
32373
+ i18n-multiCheckboxFilterSearchPlaceholder="kendo.grid.multiCheckboxFilterSearchPlaceholder|The placeholder text for the multi-checkbox filter search input"
32374
+ multiCheckboxFilterSearchPlaceholder="Search..."
32375
+
32376
+ i18n-multiCheckboxFilterSelectAllLabel="kendo.grid.multiCheckboxFilterSelectAllLabel|The label for the multi-checkbox filter select all option"
32377
+ multiCheckboxFilterSelectAllLabel="Select all"
32378
+
32379
+ i18n-multiCheckboxFilterSelectedItemsCount="kendo.grid.multiCheckboxFilterSelectedItemsCount|The text for the multi-checkbox filter selected items count"
32380
+ multiCheckboxFilterSelectedItemsCount="{{ '{selectedItemsCount} selected items' }}"
32635
32381
  >
32636
32382
  </ng-container>
32637
32383
  <kendo-grid-toolbar
@@ -33050,10 +32796,10 @@ class GridComponent {
33050
32796
  </kendo-pager-info>
33051
32797
  </ng-template>
33052
32798
  <div #dialogContainer></div>
32799
+ <div #windowContainer></div>
33053
32800
 
33054
32801
  <kendo-grid-adaptive-renderer *ngIf="isAdaptiveModeEnabled"></kendo-grid-adaptive-renderer>
33055
32802
  <kendo-resize-sensor *ngIf="isVirtual" (resize)="onResize()"></kendo-resize-sensor>
33056
- <div *ngIf="aiAssistantToolbarTool" #windowContainer></div>
33057
32803
 
33058
32804
  <div kendoWatermarkOverlay *ngIf="showLicenseWatermark" [licenseMessage]="licenseMessage"></div>
33059
32805
  `, 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 });
@@ -33492,6 +33238,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
33492
33238
 
33493
33239
  i18n-columnChooserSelectedColumnsCount="kendo.grid.columnChooserSelectedColumnsCount|The text displayed in the Column Chooser for the number of selected columns"
33494
33240
  columnChooserSelectedColumnsCount="{{ '{selectedColumnsCount} Selected items' }}"
33241
+
33242
+ i18n-multiCheckboxFilterSearchPlaceholder="kendo.grid.multiCheckboxFilterSearchPlaceholder|The placeholder text for the multi-checkbox filter search input"
33243
+ multiCheckboxFilterSearchPlaceholder="Search..."
33244
+
33245
+ i18n-multiCheckboxFilterSelectAllLabel="kendo.grid.multiCheckboxFilterSelectAllLabel|The label for the multi-checkbox filter select all option"
33246
+ multiCheckboxFilterSelectAllLabel="Select all"
33247
+
33248
+ i18n-multiCheckboxFilterSelectedItemsCount="kendo.grid.multiCheckboxFilterSelectedItemsCount|The text for the multi-checkbox filter selected items count"
33249
+ multiCheckboxFilterSelectedItemsCount="{{ '{selectedItemsCount} selected items' }}"
33495
33250
  >
33496
33251
  </ng-container>
33497
33252
  <kendo-grid-toolbar
@@ -33910,10 +33665,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
33910
33665
  </kendo-pager-info>
33911
33666
  </ng-template>
33912
33667
  <div #dialogContainer></div>
33668
+ <div #windowContainer></div>
33913
33669
 
33914
33670
  <kendo-grid-adaptive-renderer *ngIf="isAdaptiveModeEnabled"></kendo-grid-adaptive-renderer>
33915
33671
  <kendo-resize-sensor *ngIf="isVirtual" (resize)="onResize()"></kendo-resize-sensor>
33916
- <div *ngIf="aiAssistantToolbarTool" #windowContainer></div>
33917
33672
 
33918
33673
  <div kendoWatermarkOverlay *ngIf="showLicenseWatermark" [licenseMessage]="licenseMessage"></div>
33919
33674
  `,
@@ -34122,9 +33877,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
34122
33877
  }], columnMenuTemplates: [{
34123
33878
  type: ContentChildren,
34124
33879
  args: [ColumnMenuTemplateDirective]
34125
- }], aiAssistantToolbarTool: [{
34126
- type: ContentChild,
34127
- args: [AIAssistantToolbarDirective]
34128
33880
  }], lockedHeader: [{
34129
33881
  type: ViewChild,
34130
33882
  args: ['lockedHeader']
@@ -34722,7 +34474,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
34722
34474
  }] });
34723
34475
 
34724
34476
  /**
34725
- * Represents the directive that manages editing operations in the Grid when using Template-Driven Angular Forms ([see example]({% slug editing_directives_grid %}#toc-template-editing-directive)).
34477
+ * Represents the directive that manages editing operations in the Grid when using Template-Driven Angular Forms ([see example](slug:inline_editing_grid#using-template-driven-forms)).
34726
34478
  *
34727
34479
  * @example
34728
34480
  * ```html
@@ -34799,7 +34551,7 @@ const markAllAsTouched = (control) => {
34799
34551
  };
34800
34552
 
34801
34553
  /**
34802
- * Represents the directive that manages editing operations in the Grid when using Reactive Forms ([see example](slug:editing_directives_grid#toc-reactive-editing-directive)).
34554
+ * Represents the directive that manages editing operations in the Grid when using Reactive Forms ([see example](slug:inline_editing_grid#using-reactive-forms)).
34803
34555
  *
34804
34556
  * @example
34805
34557
  * ```html
@@ -34848,7 +34600,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
34848
34600
  }] } });
34849
34601
 
34850
34602
  /**
34851
- * Represent the directive that manages in-cell editing operations in the Grid when using Reactive Forms ([see example]({% slug editing_directives_grid %}#toc-in-cell-editing)).
34603
+ * Represent the directive that manages in-cell editing operations in the Grid when using Reactive Forms ([see example](slug:editing_incell_grid#quick-setup)).
34852
34604
  *
34853
34605
  * @example
34854
34606
  * ```html
@@ -34934,7 +34686,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
34934
34686
 
34935
34687
  /**
34936
34688
  * Represents the Kendo UI Grid external editing directive. The directive manages editing operations in the Grid when using the
34937
- * External Form ([see example](slug:editing_directives_grid#external-editing)).
34689
+ * External Form ([see example](slug:external_editing_grid#quick-setup)).
34938
34690
  *
34939
34691
  * @example
34940
34692
  * ```typescript
@@ -35585,6 +35337,9 @@ class GridClipboardDirective {
35585
35337
  const isPaste = operationType === 'paste';
35586
35338
  const pastedData = args.clipboardData.getData('text');
35587
35339
  const visibleCols = this.host.columns.toArray().filter(c => c.isVisible);
35340
+ if (visibleCols.some(c => c.orderIndex > 0)) { // columns have been reordered
35341
+ visibleCols.sort((a, b) => a.orderIndex - b.orderIndex);
35342
+ }
35588
35343
  const data = isPaste ?
35589
35344
  {
35590
35345
  dataString: pastedData,
@@ -37199,325 +36954,1003 @@ class CancelCommandToolbarDirective extends ToolbarEditingToolBase {
37199
36954
  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 });
37200
36955
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CancelCommandToolbarDirective, isStandalone: true, selector: "[kendoGridCancelTool]", usesInheritance: true, ngImport: i0 });
37201
36956
  }
37202
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CancelCommandToolbarDirective, decorators: [{
37203
- type: Directive,
36957
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CancelCommandToolbarDirective, decorators: [{
36958
+ type: Directive,
36959
+ args: [{
36960
+ selector: '[kendoGridCancelTool]',
36961
+ standalone: true
36962
+ }]
36963
+ }], ctorParameters: function () { return [{ type: EditService }, { type: i54.ToolBarButtonComponent }, { type: SelectionService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; } });
36964
+
36965
+ let incrementingId = 0;
36966
+ /**
36967
+ * Represents the toolbar tool for grouping columns of the Grid.
36968
+ * Use this directive on any `kendo-toolbar-button` inside a ToolbarComponent in the Grid.
36969
+ * When you click the toolbar button with this directive, the `group` event is triggered.
36970
+ *
36971
+ * @example
36972
+ * ```html
36973
+ * <kendo-grid>
36974
+ * <kendo-toolbar>
36975
+ * <kendo-toolbar-button text="Group" kendoGridGroupTool></kendo-toolbar-button>
36976
+ * </kendo-toolbar>
36977
+ * </kendo-grid>
36978
+ * ```
36979
+ * @remarks
36980
+ * Applied to: {@link ToolBarButtonComponent}.
36981
+ */
36982
+ class GroupCommandToolbarDirective {
36983
+ host;
36984
+ popupService;
36985
+ ctx;
36986
+ ngZone;
36987
+ renderer;
36988
+ adaptiveGridService;
36989
+ popupRef;
36990
+ nextId = incrementingId++;
36991
+ toolSubs = new Subscription();
36992
+ popupSubs;
36993
+ actionSheetCloseSub;
36994
+ removeClickListener;
36995
+ constructor(host, popupService, ctx, ngZone, renderer, adaptiveGridService) {
36996
+ this.host = host;
36997
+ this.popupService = popupService;
36998
+ this.ctx = ctx;
36999
+ this.ngZone = ngZone;
37000
+ this.renderer = renderer;
37001
+ this.adaptiveGridService = adaptiveGridService;
37002
+ }
37003
+ ngOnInit() {
37004
+ this.toolSubs = this.host.click.subscribe(e => this.onClick(e));
37005
+ this.toolSubs.add(this.ctx.grid.groupChange.subscribe(group => {
37006
+ this.host.showBadge = this.isGroupingApplied(group);
37007
+ }));
37008
+ this.host.hasBadgeContainer = true;
37009
+ this.host.showBadge = this.isGroupingApplied(this.ctx.grid.group);
37010
+ const hasToolbarIcon = isPresent$1(this.host.toolbarOptions.icon) && this.host.toolbarOptions.icon !== '';
37011
+ const hasOverflowIcon = isPresent$1(this.host.overflowOptions.icon) && this.host.overflowOptions.icon !== '';
37012
+ const hasIcon = hasToolbarIcon && hasOverflowIcon;
37013
+ const hasSvgIcon = isPresent$1(this.host.toolbarOptions.svgIcon) && isPresent$1(this.host.overflowOptions.svgIcon);
37014
+ if (!hasIcon) {
37015
+ this.host.icon = 'group';
37016
+ }
37017
+ if (!hasSvgIcon) {
37018
+ this.host.svgIcon = groupIcon;
37019
+ }
37020
+ }
37021
+ ngAfterViewInit() {
37022
+ if (!isPresent$1(this.host.text)) {
37023
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => {
37024
+ this.host.text = this.ctx.localization.get(`groupToolbarToolText`);
37025
+ });
37026
+ }
37027
+ this.buttonElement?.setAttribute('aria-haspopup', 'dialog');
37028
+ this.buttonElement?.setAttribute('aria-expanded', 'false');
37029
+ this.buttonElement?.setAttribute('title', this.ctx.localization.get('groupToolbarToolText'));
37030
+ }
37031
+ ngOnDestroy() {
37032
+ if (this.toolSubs) {
37033
+ this.toolSubs.unsubscribe();
37034
+ }
37035
+ if (this.popupSubs) {
37036
+ this.popupSubs.unsubscribe();
37037
+ }
37038
+ if (this.popupRef) {
37039
+ this.popupRef.close();
37040
+ this.popupRef = null;
37041
+ }
37042
+ if (this.actionSheetCloseSub) {
37043
+ this.actionSheetCloseSub.unsubscribe();
37044
+ this.actionSheetCloseSub = null;
37045
+ }
37046
+ if (this.removeClickListener) {
37047
+ this.removeClickListener();
37048
+ this.removeClickListener = null;
37049
+ }
37050
+ }
37051
+ onClick(e) {
37052
+ e.preventDefault();
37053
+ if (this.ctx.grid.adaptiveMode === 'auto' && this.adaptiveGridService.windowSize !== 'large') {
37054
+ if (!this.ctx.grid.isActionSheetExpanded) {
37055
+ this.adaptiveGridService.viewType = 'groupToolbarTool';
37056
+ this.ctx.grid.adaptiveRenderer.actionSheet.toggle(true);
37057
+ this.host.selected = true;
37058
+ this.actionSheetCloseSub = this.ctx.grid.adaptiveRenderer.actionSheet.collapse.subscribe(() => this.host.selected = false);
37059
+ }
37060
+ }
37061
+ else {
37062
+ if (this.popupRef) {
37063
+ this.closePopup();
37064
+ return;
37065
+ }
37066
+ this.openPopup();
37067
+ }
37068
+ }
37069
+ openPopup() {
37070
+ const direction = this.ctx.localization.rtl ? 'right' : 'left';
37071
+ this.popupRef = this.popupService.open({
37072
+ anchor: this.buttonElement,
37073
+ content: GroupToolbarToolComponent,
37074
+ popupClass: 'k-grid-columnmenu-popup',
37075
+ positionMode: 'absolute',
37076
+ anchorAlign: { vertical: 'bottom', horizontal: direction },
37077
+ popupAlign: { vertical: 'top', horizontal: direction }
37078
+ });
37079
+ this.adaptiveGridService.popupRef = this.popupRef;
37080
+ this.setPopupAttributes();
37081
+ this.host.selected = true;
37082
+ this.ngZone.runOutsideAngular(() => {
37083
+ if (!isDocumentAvailable()) {
37084
+ return;
37085
+ }
37086
+ this.removeClickListener = this.renderer.listen('document', 'click', (e) => {
37087
+ if (this.popupRef && !closest$1(e.target, node => node === this.popupRef.popupElement || node === this.buttonElement)) {
37088
+ this.ngZone.run(() => {
37089
+ this.closePopup();
37090
+ });
37091
+ }
37092
+ });
37093
+ });
37094
+ this.popupSubs = this.popupRef.popup.instance.anchorViewportLeave.subscribe(() => {
37095
+ this.popupSubs?.unsubscribe();
37096
+ this.popupSubs = null;
37097
+ this.closePopup();
37098
+ });
37099
+ this.initPopupProperties();
37100
+ }
37101
+ setPopupAttributes() {
37102
+ const popupElement = this.popupRef.popupElement;
37103
+ const popupId = `k-group-tool-${this.nextId}-popup`;
37104
+ const popupAriaElement = popupElement.querySelector('.k-popup');
37105
+ this.renderer.setAttribute(popupElement, 'dir', this.ctx.localization.rtl ? 'rtl' : 'ltr');
37106
+ this.renderer.setAttribute(popupAriaElement, 'id', popupId);
37107
+ this.renderer.setAttribute(popupAriaElement, 'role', 'dialog');
37108
+ this.buttonElement?.setAttribute('aria-expanded', 'true');
37109
+ this.buttonElement?.setAttribute('aria-controls', popupId);
37110
+ }
37111
+ initPopupProperties() {
37112
+ this.popupRef.content.instance.ctx = this.ctx;
37113
+ this.popupRef.content.instance.hostButton = this.host;
37114
+ this.popupSubs.add(this.popupRef.content.instance.groupClear.subscribe(() => {
37115
+ this.closePopup();
37116
+ }));
37117
+ this.popupSubs.add(this.popupRef.content.instance.close.subscribe(() => {
37118
+ this.closePopup();
37119
+ }));
37120
+ }
37121
+ closePopup() {
37122
+ this.buttonElement?.setAttribute('aria-expanded', 'false');
37123
+ this.buttonElement?.removeAttribute('aria-controls');
37124
+ this.host.selected = false;
37125
+ if (this.popupRef) {
37126
+ this.popupRef.close();
37127
+ this.popupRef = null;
37128
+ }
37129
+ if (this.popupSubs) {
37130
+ this.popupSubs.unsubscribe();
37131
+ this.popupSubs = null;
37132
+ }
37133
+ if (this.removeClickListener) {
37134
+ this.removeClickListener();
37135
+ this.removeClickListener = null;
37136
+ }
37137
+ }
37138
+ get buttonElement() {
37139
+ return this.host.getButton();
37140
+ }
37141
+ isGroupingApplied(group) {
37142
+ return isPresent$1(group) && group.length > 0;
37143
+ }
37144
+ 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 });
37145
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupCommandToolbarDirective, isStandalone: true, selector: "[kendoGridGroupTool]", ngImport: i0 });
37146
+ }
37147
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupCommandToolbarDirective, decorators: [{
37148
+ type: Directive,
37149
+ args: [{
37150
+ selector: '[kendoGridGroupTool]',
37151
+ standalone: true
37152
+ }]
37153
+ }], ctorParameters: function () { return [{ type: i54.ToolBarButtonComponent }, { type: i2.PopupService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: AdaptiveGridService }]; } });
37154
+
37155
+ /**
37156
+ * Stores the row and cell highlight state of the Grid.
37157
+ *
37158
+ * @example
37159
+ * ```typescript
37160
+ * <kendo-grid kendoGridHighlight="ProductID"></kendo-grid>
37161
+ *
37162
+ * <kendo-grid [kendoGridHighlight]="myKey"></kendo-grid>
37163
+ * ```
37164
+ * @remarks
37165
+ * Applied to: {@link GridComponent}.
37166
+ */
37167
+ class HighlightDirective {
37168
+ ctx;
37169
+ /**
37170
+ * Stores the highlighted items keys.
37171
+ * @default []
37172
+ */
37173
+ highlightedKeys = [];
37174
+ /**
37175
+ * Sets the item key to store in `highlightedKeys`. The Grid uses the row index as the default item key.
37176
+ */
37177
+ highlightItemKey;
37178
+ /**
37179
+ * Sets the column key for a data cell. The Grid uses the column index as the default column key.
37180
+ */
37181
+ highlightColumnKey;
37182
+ rowHighlightState = new Set();
37183
+ cellHighlightState = new PairSet();
37184
+ constructor(ctx) {
37185
+ this.ctx = ctx;
37186
+ this.ctx.highlightDirective = this;
37187
+ }
37188
+ ngOnChanges(changes) {
37189
+ if (isPresent$1(changes['highlightedKeys'])) {
37190
+ this.setState(this.highlightedKeys);
37191
+ }
37192
+ }
37193
+ ngOnDestroy() {
37194
+ this.reset();
37195
+ this.ctx.highlightDirective = null;
37196
+ }
37197
+ /**
37198
+ * @hidden
37199
+ */
37200
+ isRowHighlighted(row) {
37201
+ return this.rowHighlightState.has(this.getItemKey(row));
37202
+ }
37203
+ /**
37204
+ * @hidden
37205
+ */
37206
+ isCellHighlighted(row, column, colIndex) {
37207
+ const highlightItem = this.getHighlightItem(row, column, colIndex);
37208
+ return this.cellHighlightState.has(highlightItem.itemKey, highlightItem.columnKey);
37209
+ }
37210
+ getItemKey(row) {
37211
+ if (this.highlightItemKey) {
37212
+ if (typeof this.highlightItemKey === "string") {
37213
+ return row.data?.[this.highlightItemKey];
37214
+ }
37215
+ if (typeof this.highlightItemKey === "function") {
37216
+ return this.highlightItemKey(row);
37217
+ }
37218
+ }
37219
+ return row.index;
37220
+ }
37221
+ getHighlightItem(row, col, colIndex) {
37222
+ const itemIdentifiers = {};
37223
+ itemIdentifiers.itemKey = this.getItemKey(row);
37224
+ if (!isPresent$1(col) && !isPresent$1(colIndex)) {
37225
+ return itemIdentifiers;
37226
+ }
37227
+ if (this.highlightColumnKey) {
37228
+ if (typeof this.highlightColumnKey === "string") {
37229
+ itemIdentifiers.columnKey = row.dataItem[this.highlightColumnKey];
37230
+ }
37231
+ if (typeof this.highlightColumnKey === "function") {
37232
+ itemIdentifiers.columnKey = this.highlightColumnKey(col, colIndex);
37233
+ }
37234
+ }
37235
+ return {
37236
+ itemKey: itemIdentifiers.itemKey,
37237
+ columnKey: itemIdentifiers.columnKey ? itemIdentifiers.columnKey : colIndex
37238
+ };
37239
+ }
37240
+ setState(highlightedKeys) {
37241
+ this.reset();
37242
+ if (!highlightedKeys || highlightedKeys.length === 0) {
37243
+ return;
37244
+ }
37245
+ const rowHighlights = highlightedKeys.filter(item => !isPresent$1(item.columnKey));
37246
+ const cellHighlights = highlightedKeys.filter(item => isPresent$1(item.columnKey));
37247
+ if (cellHighlights.length > 0) {
37248
+ this.cellHighlightState = new PairSet(cellHighlights, 'itemKey', 'columnKey');
37249
+ }
37250
+ if (rowHighlights.length > 0) {
37251
+ rowHighlights.forEach(item => {
37252
+ this.rowHighlightState.add(item.itemKey);
37253
+ });
37254
+ }
37255
+ }
37256
+ reset() {
37257
+ this.rowHighlightState.clear();
37258
+ this.cellHighlightState.clear();
37259
+ }
37260
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HighlightDirective, deps: [{ token: ContextService }], target: i0.ɵɵFactoryTarget.Directive });
37261
+ 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 });
37262
+ }
37263
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HighlightDirective, decorators: [{
37264
+ type: Directive,
37265
+ args: [{
37266
+ selector: '[kendoGridHighlight]',
37267
+ standalone: true
37268
+ }]
37269
+ }], ctorParameters: function () { return [{ type: ContextService }]; }, propDecorators: { highlightedKeys: [{
37270
+ type: Input
37271
+ }], highlightItemKey: [{
37272
+ type: Input,
37273
+ args: ["kendoGridHighlight"]
37274
+ }], highlightColumnKey: [{
37275
+ type: Input
37276
+ }] } });
37277
+
37278
+ /**
37279
+ * @hidden
37280
+ */
37281
+ const DEFAULT_AI_REQUEST_OPTIONS = {
37282
+ headers: new HttpHeaders({
37283
+ 'Content-Type': 'application/json'
37284
+ }),
37285
+ role: 'user',
37286
+ method: 'POST',
37287
+ responseType: 'json'
37288
+ };
37289
+ /**
37290
+ * Represents the event data when the AI Assistant request completes successfully.
37291
+ */
37292
+ class GridToolbarAIResponseSuccessEvent extends PreventableEvent$1 {
37293
+ /**
37294
+ * The HTTP response from the AI service.
37295
+ */
37296
+ response;
37297
+ constructor(response) {
37298
+ super();
37299
+ this.response = response;
37300
+ }
37301
+ }
37302
+ /**
37303
+ * Represents the event data when the AI Assistant request completes with an error.
37304
+ */
37305
+ class GridToolbarAIResponseErrorEvent extends PreventableEvent$1 {
37306
+ /**
37307
+ * The HTTP error response from the AI service.
37308
+ */
37309
+ error;
37310
+ constructor(error) {
37311
+ super();
37312
+ this.error = error;
37313
+ }
37314
+ }
37315
+
37316
+ /**
37317
+ * @hidden
37318
+ * Converts date strings in a filter to Date objects.
37319
+ */
37320
+ const convertDateStringsInFilter = (filter) => {
37321
+ if (!filter) {
37322
+ return filter;
37323
+ }
37324
+ if (filter.filters && Array.isArray(filter.filters)) {
37325
+ return {
37326
+ ...filter,
37327
+ filters: filter.filters.map(f => convertDateStringsInFilter(f))
37328
+ };
37329
+ }
37330
+ if (filter.field && filter.value !== undefined) {
37331
+ if (typeof filter.value === 'string' && isDateOperator(filter.operator)) {
37332
+ const date = parseDate(filter.value);
37333
+ return {
37334
+ ...filter,
37335
+ value: date || filter.value
37336
+ };
37337
+ }
37338
+ }
37339
+ return filter;
37340
+ };
37341
+ /**
37342
+ * @hidden
37343
+ */
37344
+ const isDateOperator = (operator) => {
37345
+ const dateOperators = [
37346
+ 'eq', 'neq', 'lt', 'lte', 'gt', 'gte'
37347
+ ];
37348
+ return dateOperators.includes(operator);
37349
+ };
37350
+ /**
37351
+ * @hidden
37352
+ * Processes cell highlights for a specific filter and item.
37353
+ */
37354
+ const processCellHighlights = (filter, rowIndex, columns, highlightItems) => {
37355
+ Object.keys(filter.cells).forEach((columnField) => {
37356
+ const actualColumnIndex = Array.from(columns).findIndex((col) => col.field === columnField);
37357
+ if (actualColumnIndex !== -1) {
37358
+ highlightItems.push({
37359
+ itemKey: rowIndex,
37360
+ columnKey: actualColumnIndex,
37361
+ });
37362
+ }
37363
+ });
37364
+ };
37365
+ /**
37366
+ * @hidden
37367
+ * Processes filtered results and adds highlight items.
37368
+ */
37369
+ const processFilteredResults = (filteredResults, data, filter, columns, highlightItems) => {
37370
+ filteredResults?.forEach((item) => {
37371
+ const rowIndex = data.findIndex((dataItem) => dataItem === item);
37372
+ if (filter.cells && Object.keys(filter.cells).length > 0) {
37373
+ processCellHighlights(filter, rowIndex, columns, highlightItems);
37374
+ }
37375
+ else {
37376
+ highlightItems.push({
37377
+ itemKey: rowIndex,
37378
+ });
37379
+ }
37380
+ });
37381
+ };
37382
+ /**
37383
+ * @hidden
37384
+ * Highlights items in a grid based on the provided filters and columns.
37385
+ * @param data - The data to be highlighted.
37386
+ * @param filters - The composite highlight descriptors containing the filters and logic.
37387
+ * @param columns - The columns of the grid.
37388
+ * @returns An array of HighlightItem objects representing the highlighted items.
37389
+ */
37390
+ const highlightBy = (data, filters, columns) => {
37391
+ const highlightItems = [];
37392
+ filters.forEach((filter) => {
37393
+ const processedFilters = filter.filters.map((filter) => convertDateStringsInFilter(filter));
37394
+ const filteredResults = filterBy(data, {
37395
+ logic: filter.logic || "and",
37396
+ filters: processedFilters,
37397
+ });
37398
+ processFilteredResults(filteredResults, data, filter, columns, highlightItems);
37399
+ });
37400
+ return highlightItems;
37401
+ };
37402
+
37403
+ /**
37404
+ * @hidden
37405
+ */
37406
+ class AiAssistantComponent {
37407
+ http;
37408
+ ctx;
37409
+ columnInfoService;
37410
+ aiPrompt;
37411
+ activeView = 0;
37412
+ requestUrl;
37413
+ requestOptions;
37414
+ aiPromptSettings;
37415
+ aiToolDirective;
37416
+ streaming = false;
37417
+ disabledGenerateButton = false;
37418
+ lastMessage;
37419
+ requestData;
37420
+ currentRequestSubscription = null;
37421
+ //Remove this when the AI Assistant has a built-in loading indicator
37422
+ loadingOutput = { id: 'k-loading-item', output: '', prompt: '' };
37423
+ columns = [];
37424
+ idCounter = 0;
37425
+ constructor(http, ctx, columnInfoService) {
37426
+ this.http = http;
37427
+ this.ctx = ctx;
37428
+ this.columnInfoService = columnInfoService;
37429
+ }
37430
+ ngAfterViewInit() {
37431
+ this.columns = this.columnInfoService.leafNamedColumns.map((col) => ({ field: col.field }));
37432
+ }
37433
+ ngOnDestroy() {
37434
+ this.unsubscribeCurrentRequest();
37435
+ }
37436
+ message(message) {
37437
+ return this.ctx.localization.get(message);
37438
+ }
37439
+ cancelRequest() {
37440
+ this.aiToolDirective.cancelRequest.emit();
37441
+ this.unsubscribeCurrentRequest();
37442
+ this.streaming = false;
37443
+ }
37444
+ onPromptRequest(ev) {
37445
+ if (this.aiToolDirective.promptOutputs.length === 0) {
37446
+ this.aiToolDirective.promptOutputs.push(this.loadingOutput);
37447
+ }
37448
+ this.unsubscribeCurrentRequest();
37449
+ this.streaming = true;
37450
+ this.activeView = 1;
37451
+ if (ev.prompt) {
37452
+ this.lastMessage = ev.prompt;
37453
+ }
37454
+ this.requestData = {
37455
+ columns: this.columns,
37456
+ promptMessage: ev.prompt,
37457
+ url: this.requestUrl,
37458
+ requestOptions: {
37459
+ ...this.requestOptions
37460
+ }
37461
+ };
37462
+ if (!this.requestOptions.body) {
37463
+ const requestBody = {
37464
+ role: this.requestData.requestOptions.role,
37465
+ contents: [
37466
+ {
37467
+ text: this.requestData.promptMessage
37468
+ }
37469
+ ],
37470
+ columns: this.requestData.columns
37471
+ };
37472
+ this.requestData.requestOptions.body = requestBody;
37473
+ }
37474
+ this.aiToolDirective.promptRequest.emit({ requestData: this.requestData, isRetry: ev.isRetry });
37475
+ if (!this.requestUrl) {
37476
+ return;
37477
+ }
37478
+ this.currentRequestSubscription = this.sendPromptRequest().subscribe((res) => {
37479
+ if (res.body) {
37480
+ this.processResponse(res);
37481
+ this.streaming = false;
37482
+ }
37483
+ this.currentRequestSubscription = null;
37484
+ }, (error) => {
37485
+ this.handleError(error);
37486
+ this.streaming = false;
37487
+ this.currentRequestSubscription = null;
37488
+ });
37489
+ }
37490
+ sendPromptRequest() {
37491
+ const request = new HttpRequest(this.requestData.requestOptions.method, this.requestData.url, this.requestData.requestOptions.body, this.requestData.requestOptions);
37492
+ return this.http.request(request);
37493
+ }
37494
+ processResponse(response) {
37495
+ if (this.aiToolDirective.autoClose) {
37496
+ this.aiToolDirective.emitOpenClose = true;
37497
+ this.aiToolDirective.toggleWindow();
37498
+ }
37499
+ const responseBody = response.body;
37500
+ const responseSuccessEvent = new GridToolbarAIResponseSuccessEvent(response);
37501
+ this.aiToolDirective.responseSuccess.emit(responseSuccessEvent);
37502
+ if (responseSuccessEvent.isDefaultPrevented()) {
37503
+ this.deleteLoadingOutput();
37504
+ return;
37505
+ }
37506
+ const isFilterable = Boolean(this.ctx.grid.filterable);
37507
+ const isSortable = Boolean(this.ctx.grid.sortable);
37508
+ const isGroupable = Boolean(this.ctx.grid.groupable);
37509
+ if (isFilterable && responseBody.filter) {
37510
+ this.processFilterResponse(responseBody.filter);
37511
+ }
37512
+ if (isSortable && responseBody.sort) {
37513
+ this.processArrayResponse(responseBody.sort, this.ctx.grid.currentState.sort || [], (item) => item.field, (mergedArray) => this.ctx.grid.sortChange.next(mergedArray));
37514
+ }
37515
+ if (isGroupable && responseBody.group) {
37516
+ this.processArrayResponse(responseBody.group, this.ctx.grid.currentState.group || [], (item) => item.field, (mergedArray) => this.ctx.grid.groupChange.next(mergedArray));
37517
+ }
37518
+ if (this.ctx.highlightDirective && responseBody.highlight) {
37519
+ this.processHighlightResponse(responseBody.highlight);
37520
+ }
37521
+ const responseContentStart = [`${this.ctx.localization.get('aiAssistantOutputCardBodyContent')} \n`];
37522
+ const responseContentBody = responseBody.messages
37523
+ .map((output, idx) => `${idx + 1} ${output}`)
37524
+ .join('\n');
37525
+ const output = {
37526
+ id: this.idCounter++,
37527
+ title: this.ctx.localization.get('aiAssistantOutputCardTitle'),
37528
+ prompt: this.lastMessage,
37529
+ output: responseContentStart.concat(responseContentBody).join(''),
37530
+ };
37531
+ this.deleteLoadingOutput();
37532
+ this.aiToolDirective.promptOutputs.unshift(output);
37533
+ }
37534
+ handleError(error) {
37535
+ const responseErrorEvent = new GridToolbarAIResponseErrorEvent(error);
37536
+ this.aiToolDirective.responseError.emit(responseErrorEvent);
37537
+ if (responseErrorEvent.isDefaultPrevented()) {
37538
+ this.deleteLoadingOutput();
37539
+ return;
37540
+ }
37541
+ const output = {
37542
+ id: this.idCounter++,
37543
+ prompt: this.lastMessage,
37544
+ output: error.message
37545
+ };
37546
+ this.deleteLoadingOutput();
37547
+ this.aiToolDirective.promptOutputs.unshift(output);
37548
+ }
37549
+ deleteLoadingOutput() {
37550
+ if (this.aiToolDirective.promptOutputs[0]?.id === this.loadingOutput.id) {
37551
+ this.aiToolDirective.promptOutputs.splice(0, 1);
37552
+ }
37553
+ }
37554
+ unsubscribeCurrentRequest() {
37555
+ if (this.currentRequestSubscription) {
37556
+ this.currentRequestSubscription.unsubscribe();
37557
+ this.currentRequestSubscription = null;
37558
+ }
37559
+ }
37560
+ processArrayResponse(newItems, currentItems, getField, updateGrid) {
37561
+ if (newItems?.length === 0) {
37562
+ updateGrid([]);
37563
+ }
37564
+ else if (newItems?.length) {
37565
+ let mergedArray = [...newItems];
37566
+ const newFields = newItems.map(getField);
37567
+ const existingItemsToKeep = currentItems.filter(item => !newFields.includes(getField(item)));
37568
+ mergedArray = [...mergedArray, ...existingItemsToKeep];
37569
+ updateGrid(mergedArray);
37570
+ }
37571
+ }
37572
+ processHighlightResponse(highlight) {
37573
+ if (highlight.length === 0) {
37574
+ this.ctx.highlightDirective['setState']([]);
37575
+ return;
37576
+ }
37577
+ const highlightedItems = highlightBy(this.ctx.dataBindingDirective['originalData'], highlight, this.columns);
37578
+ this.ctx.highlightDirective['setState'](highlightedItems);
37579
+ }
37580
+ processFilterResponse(filter) {
37581
+ const processedFilter = convertDateStringsInFilter(filter);
37582
+ const clearFilter = Object.keys(processedFilter).length === 0;
37583
+ if (clearFilter) {
37584
+ this.ctx.grid.filterChange.next(undefined);
37585
+ }
37586
+ else if (processedFilter?.filters.length) {
37587
+ const currentFilter = this.ctx.grid.currentState.filter;
37588
+ let mergedFilter = processedFilter;
37589
+ if (currentFilter && currentFilter.filters?.length > 0) {
37590
+ mergedFilter = {
37591
+ logic: 'and',
37592
+ filters: [
37593
+ currentFilter,
37594
+ processedFilter
37595
+ ]
37596
+ };
37597
+ }
37598
+ this.ctx.grid.filterChange.next(mergedFilter);
37599
+ }
37600
+ }
37601
+ 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 });
37602
+ 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: `
37603
+ <kendo-aiprompt
37604
+ #aiPrompt
37605
+ [promptSuggestions]="aiPromptSettings?.promptSuggestions"
37606
+ [showOutputRating]="aiPromptSettings?.showOutputRating"
37607
+ [streaming]="streaming"
37608
+ [speechToTextButton]="aiPromptSettings?.speechToTextButton"
37609
+ [(activeView)]="activeView"
37610
+ [generateButtonSVGIcon]="aiPromptSettings?.generateButtonSVGIcon"
37611
+ [generateButtonIcon]="aiPromptSettings?.generateButtonIcon"
37612
+ [disabledGenerateButton]="disabledGenerateButton || promptView.textAreaValue?.length === 0"
37613
+ [promptOutputs]="aiPromptSettings?.promptOutputs"
37614
+ [textAreaSettings]="aiPromptSettings?.textAreaSettings"
37615
+ (promptRequest)="onPromptRequest($event)"
37616
+ (promptRequestCancel)="cancelRequest()"
37617
+ >
37618
+ <kendo-aiprompt-prompt-view #promptView></kendo-aiprompt-prompt-view>
37619
+ <kendo-aiprompt-output-view></kendo-aiprompt-output-view>
37620
+ <ng-template *ngIf="streaming && aiPrompt.streaming" kendoAIPromptOutputTemplate let-output>
37621
+ <div class="k-card">
37622
+ <div class="k-card-header">
37623
+ <div class="k-card-title">
37624
+ <span class="k-skeleton k-skeleton-text k-skeleton-pulse" [style.width.px]="200"></span>
37625
+ </div>
37626
+ <div class="k-card-subtitle">
37627
+ <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
37628
+ </div>
37629
+ </div>
37630
+ <div class="k-card-body">
37631
+ <span class="k-skeleton k-skeleton-rect k-skeleton-pulse" style="height: 80px;"></span>
37632
+ </div>
37633
+ <div class="k-card-actions">
37634
+ <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
37635
+ </div>
37636
+ </div>
37637
+ </ng-template>
37638
+ <ng-template *ngIf="!(streaming && aiPrompt.streaming)" kendoAIPromptOutputBodyTemplate let-output>
37639
+ <p>{{output.output}}</p>
37640
+ </ng-template>
37641
+ <kendo-aiprompt-messages
37642
+ [generateOutput]="message('aiAssistantApplyButtonText')"
37643
+ ></kendo-aiprompt-messages>
37644
+ </kendo-aiprompt>
37645
+ `, 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]" }] });
37646
+ }
37647
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AiAssistantComponent, decorators: [{
37648
+ type: Component,
37204
37649
  args: [{
37205
- selector: '[kendoGridCancelTool]',
37206
- standalone: true
37650
+ standalone: true,
37651
+ imports: [NgIf, AIPromptComponent, AIPromptCustomMessagesComponent, PromptViewComponent, OutputViewComponent, AIPromptOutputTemplateDirective, AIPromptOutputBodyTemplateDirective],
37652
+ template: `
37653
+ <kendo-aiprompt
37654
+ #aiPrompt
37655
+ [promptSuggestions]="aiPromptSettings?.promptSuggestions"
37656
+ [showOutputRating]="aiPromptSettings?.showOutputRating"
37657
+ [streaming]="streaming"
37658
+ [speechToTextButton]="aiPromptSettings?.speechToTextButton"
37659
+ [(activeView)]="activeView"
37660
+ [generateButtonSVGIcon]="aiPromptSettings?.generateButtonSVGIcon"
37661
+ [generateButtonIcon]="aiPromptSettings?.generateButtonIcon"
37662
+ [disabledGenerateButton]="disabledGenerateButton || promptView.textAreaValue?.length === 0"
37663
+ [promptOutputs]="aiPromptSettings?.promptOutputs"
37664
+ [textAreaSettings]="aiPromptSettings?.textAreaSettings"
37665
+ (promptRequest)="onPromptRequest($event)"
37666
+ (promptRequestCancel)="cancelRequest()"
37667
+ >
37668
+ <kendo-aiprompt-prompt-view #promptView></kendo-aiprompt-prompt-view>
37669
+ <kendo-aiprompt-output-view></kendo-aiprompt-output-view>
37670
+ <ng-template *ngIf="streaming && aiPrompt.streaming" kendoAIPromptOutputTemplate let-output>
37671
+ <div class="k-card">
37672
+ <div class="k-card-header">
37673
+ <div class="k-card-title">
37674
+ <span class="k-skeleton k-skeleton-text k-skeleton-pulse" [style.width.px]="200"></span>
37675
+ </div>
37676
+ <div class="k-card-subtitle">
37677
+ <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
37678
+ </div>
37679
+ </div>
37680
+ <div class="k-card-body">
37681
+ <span class="k-skeleton k-skeleton-rect k-skeleton-pulse" style="height: 80px;"></span>
37682
+ </div>
37683
+ <div class="k-card-actions">
37684
+ <span class="k-skeleton k-skeleton-text k-skeleton-pulse" style="width: 100%;"></span>
37685
+ </div>
37686
+ </div>
37687
+ </ng-template>
37688
+ <ng-template *ngIf="!(streaming && aiPrompt.streaming)" kendoAIPromptOutputBodyTemplate let-output>
37689
+ <p>{{output.output}}</p>
37690
+ </ng-template>
37691
+ <kendo-aiprompt-messages
37692
+ [generateOutput]="message('aiAssistantApplyButtonText')"
37693
+ ></kendo-aiprompt-messages>
37694
+ </kendo-aiprompt>
37695
+ `
37207
37696
  }]
37208
- }], ctorParameters: function () { return [{ type: EditService }, { type: i54.ToolBarButtonComponent }, { type: SelectionService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; } });
37697
+ }], ctorParameters: function () { return [{ type: i1$8.HttpClient }, { type: ContextService }, { type: ColumnInfoService }]; }, propDecorators: { aiPrompt: [{
37698
+ type: ViewChild,
37699
+ args: [AIPromptComponent]
37700
+ }] } });
37209
37701
 
37210
- let incrementingId = 0;
37211
37702
  /**
37212
- * Represents the toolbar tool for grouping columns of the Grid.
37703
+ * Represents an AI Assistant tool of the Grid.
37213
37704
  * Use this directive on any `kendo-toolbar-button` inside a ToolbarComponent in the Grid.
37214
- * When you click the toolbar button with this directive, the `group` event is triggered.
37215
37705
  *
37216
37706
  * @example
37217
- * ```html
37707
+ * ```html-no-run
37218
37708
  * <kendo-grid>
37219
37709
  * <kendo-toolbar>
37220
- * <kendo-toolbar-button text="Group" kendoGridGroupTool></kendo-toolbar-button>
37710
+ * <kendo-toolbar-button kendoGridAIAssistantTool></kendo-toolbar-button>
37221
37711
  * </kendo-toolbar>
37222
37712
  * </kendo-grid>
37223
37713
  * ```
37224
37714
  * @remarks
37225
37715
  * Applied to: {@link ToolBarButtonComponent}.
37226
37716
  */
37227
- class GroupCommandToolbarDirective {
37717
+ class AIAssistantToolbarDirective extends ToolbarToolBase {
37718
+ windowService;
37228
37719
  host;
37229
- popupService;
37230
37720
  ctx;
37231
- ngZone;
37232
- renderer;
37233
- adaptiveGridService;
37234
- popupRef;
37235
- nextId = incrementingId++;
37236
- toolSubs = new Subscription();
37237
- popupSubs;
37238
- actionSheetCloseSub;
37239
- removeClickListener;
37240
- constructor(host, popupService, ctx, ngZone, renderer, adaptiveGridService) {
37721
+ zone;
37722
+ refresh;
37723
+ /**
37724
+ * The URL to which the AI Assistant tool sends the AI request.
37725
+ * - 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.
37726
+ * - 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.
37727
+ */
37728
+ requestUrl;
37729
+ /**
37730
+ * Configures the request options that the AI Assistant tool sends with the AI request.
37731
+ *
37732
+ * @default { headers: new HttpHeaders({ 'Content-Type': 'application/json' }), role: 'user', method: 'POST', responseType: 'json', withCredentials: false }
37733
+ */
37734
+ requestOptions;
37735
+ /**
37736
+ * Configures the initial settings for the AI Assistant Window when opened.
37737
+ */
37738
+ aiWindowSettings;
37739
+ /**
37740
+ * Configures the initial settings for the AI Prompt component that the AI Assistant Window component uses when opened.
37741
+ */
37742
+ aiPromptSettings;
37743
+ /**
37744
+ * Determines whether to close the AI Assistant Window automatically after a successful request.
37745
+ * @default true
37746
+ */
37747
+ autoClose = true;
37748
+ /**
37749
+ * Determines whether to keep the AI Prompt's outputs after closing the AI Assistant Window.
37750
+ * @default false
37751
+ */
37752
+ keepOutputHistory = false;
37753
+ /**
37754
+ * Emits an event before the AI Assistant tool sends the AI request.
37755
+ * - When you provide a `requestUrl`, you can handle the event to modify the request options.
37756
+ * - When you do not provide a `requestUrl`, you can handle the event to perform an entirely custom request.
37757
+ */
37758
+ promptRequest = new EventEmitter();
37759
+ /**
37760
+ * Emits an event when the user clicks the cancel button.
37761
+ */
37762
+ cancelRequest = new EventEmitter();
37763
+ /**
37764
+ * Emits an event when the AI Assistant tool completes the AI request successfully.
37765
+ * The event contains the response from the AI service and is preventable to allow stopping the default response handling.
37766
+ */
37767
+ responseSuccess = new EventEmitter();
37768
+ /**
37769
+ * Emits an event when the AI Assistant tool completes the AI request with an error.
37770
+ * The event contains the error response from the AI service and is preventable to allow stopping the default error handling.
37771
+ */
37772
+ responseError = new EventEmitter();
37773
+ /**
37774
+ * Emits an event when the AI Assistant tool closes.
37775
+ */
37776
+ close = new EventEmitter();
37777
+ /**
37778
+ * Emits an event when the AI Assistant tool opens.
37779
+ */
37780
+ open = new EventEmitter();
37781
+ tableWizardIcon = tableWizardIcon;
37782
+ emitOpenClose = false;
37783
+ promptOutputs = [];
37784
+ windowRef;
37785
+ subs = new Subscription();
37786
+ defaultAiPromptSettings = {
37787
+ speechToTextButton: true,
37788
+ generateButtonSVGIcon: this.tableWizardIcon,
37789
+ generateButtonIcon: 'table-wizard'
37790
+ };
37791
+ constructor(windowService, host, ctx, zone, refresh, cdr) {
37792
+ super(host, ToolbarToolName.aiAssistant, ctx, zone, cdr);
37793
+ this.windowService = windowService;
37241
37794
  this.host = host;
37242
- this.popupService = popupService;
37243
37795
  this.ctx = ctx;
37244
- this.ngZone = ngZone;
37245
- this.renderer = renderer;
37246
- this.adaptiveGridService = adaptiveGridService;
37796
+ this.zone = zone;
37797
+ this.refresh = refresh;
37798
+ this.host.rounded = 'full';
37799
+ this.host.themeColor = 'primary';
37800
+ this.host.showText = 'never';
37247
37801
  }
37248
37802
  ngOnInit() {
37249
- this.toolSubs = this.host.click.subscribe(e => this.onClick(e));
37250
- this.toolSubs.add(this.ctx.grid.groupChange.subscribe(group => {
37251
- this.host.showBadge = this.isGroupingApplied(group);
37252
- }));
37253
- this.host.hasBadgeContainer = true;
37254
- this.host.showBadge = this.isGroupingApplied(this.ctx.grid.group);
37803
+ this.subs.add(this.host.click.subscribe(() => this.onClick()));
37255
37804
  const hasToolbarIcon = isPresent$1(this.host.toolbarOptions.icon) && this.host.toolbarOptions.icon !== '';
37256
37805
  const hasOverflowIcon = isPresent$1(this.host.overflowOptions.icon) && this.host.overflowOptions.icon !== '';
37257
37806
  const hasIcon = hasToolbarIcon && hasOverflowIcon;
37258
37807
  const hasSvgIcon = isPresent$1(this.host.toolbarOptions.svgIcon) && isPresent$1(this.host.overflowOptions.svgIcon);
37259
37808
  if (!hasIcon) {
37260
- this.host.icon = 'group';
37809
+ this.host.icon = 'sparkles';
37261
37810
  }
37262
37811
  if (!hasSvgIcon) {
37263
- this.host.svgIcon = groupIcon;
37812
+ this.host.svgIcon = sparklesIcon;
37264
37813
  }
37814
+ this.requestOptions = { ...DEFAULT_AI_REQUEST_OPTIONS, ...this.requestOptions };
37265
37815
  }
37266
37816
  ngAfterViewInit() {
37267
- if (!isPresent$1(this.host.text)) {
37268
- this.ngZone.onStable.pipe(take(1)).subscribe(() => {
37269
- this.host.text = this.ctx.localization.get(`groupToolbarToolText`);
37270
- });
37271
- }
37272
- this.buttonElement?.setAttribute('aria-haspopup', 'dialog');
37273
- this.buttonElement?.setAttribute('aria-expanded', 'false');
37274
- this.buttonElement?.setAttribute('title', this.ctx.localization.get('groupToolbarToolText'));
37275
- }
37276
- ngOnDestroy() {
37277
- if (this.toolSubs) {
37278
- this.toolSubs.unsubscribe();
37279
- }
37280
- if (this.popupSubs) {
37281
- this.popupSubs.unsubscribe();
37282
- }
37283
- if (this.popupRef) {
37284
- this.popupRef.close();
37285
- this.popupRef = null;
37286
- }
37287
- if (this.actionSheetCloseSub) {
37288
- this.actionSheetCloseSub.unsubscribe();
37289
- this.actionSheetCloseSub = null;
37290
- }
37291
- if (this.removeClickListener) {
37292
- this.removeClickListener();
37293
- this.removeClickListener = null;
37294
- }
37295
- }
37296
- onClick(e) {
37297
- e.preventDefault();
37298
- if (this.ctx.grid.adaptiveMode === 'auto' && this.adaptiveGridService.windowSize !== 'large') {
37299
- if (!this.ctx.grid.isActionSheetExpanded) {
37300
- this.adaptiveGridService.viewType = 'groupToolbarTool';
37301
- this.ctx.grid.adaptiveRenderer.actionSheet.toggle(true);
37302
- this.host.selected = true;
37303
- this.actionSheetCloseSub = this.ctx.grid.adaptiveRenderer.actionSheet.collapse.subscribe(() => this.host.selected = false);
37304
- }
37305
- }
37306
- else {
37307
- if (this.popupRef) {
37308
- this.closePopup();
37309
- return;
37817
+ super.ngAfterViewInit();
37818
+ this.zone.onStable.pipe(take(1)).subscribe(() => {
37819
+ this.buttonElement?.setAttribute('aria-haspopup', 'dialog');
37820
+ this.buttonElement?.setAttribute('aria-expanded', 'false');
37821
+ const needsTitle = this.host.showText !== 'always' && this.host.showText !== 'toolbar';
37822
+ if (needsTitle && !this.host.title) {
37823
+ this.buttonElement?.setAttribute('title', this.ctx.localization.get('aiAssistantToolbarToolText'));
37310
37824
  }
37311
- this.openPopup();
37312
- }
37313
- }
37314
- openPopup() {
37315
- const direction = this.ctx.localization.rtl ? 'right' : 'left';
37316
- this.popupRef = this.popupService.open({
37317
- anchor: this.buttonElement,
37318
- content: GroupToolbarToolComponent,
37319
- popupClass: 'k-grid-columnmenu-popup',
37320
- positionMode: 'absolute',
37321
- anchorAlign: { vertical: 'bottom', horizontal: direction },
37322
- popupAlign: { vertical: 'top', horizontal: direction }
37323
37825
  });
37324
- this.adaptiveGridService.popupRef = this.popupRef;
37325
- this.setPopupAttributes();
37326
- this.host.selected = true;
37327
- this.ngZone.runOutsideAngular(() => {
37328
- if (!isDocumentAvailable()) {
37329
- return;
37826
+ this.subs.add(this.refresh.onRefresh.pipe(filter((tool) => tool === this.host)).subscribe((tool) => {
37827
+ if (tool.overflows && this.windowRef) {
37828
+ this.windowRef.close();
37330
37829
  }
37331
- this.removeClickListener = this.renderer.listen('document', 'click', (e) => {
37332
- if (this.popupRef && !closest$1(e.target, node => node === this.popupRef.popupElement || node === this.buttonElement)) {
37333
- this.ngZone.run(() => {
37334
- this.closePopup();
37335
- });
37336
- }
37337
- });
37338
- });
37339
- this.popupSubs = this.popupRef.popup.instance.anchorViewportLeave.subscribe(() => {
37340
- this.popupSubs?.unsubscribe();
37341
- this.popupSubs = null;
37342
- this.closePopup();
37343
- });
37344
- this.initPopupProperties();
37345
- }
37346
- setPopupAttributes() {
37347
- const popupElement = this.popupRef.popupElement;
37348
- const popupId = `k-group-tool-${this.nextId}-popup`;
37349
- const popupAriaElement = popupElement.querySelector('.k-popup');
37350
- this.renderer.setAttribute(popupElement, 'dir', this.ctx.localization.rtl ? 'rtl' : 'ltr');
37351
- this.renderer.setAttribute(popupAriaElement, 'id', popupId);
37352
- this.renderer.setAttribute(popupAriaElement, 'role', 'dialog');
37353
- this.buttonElement?.setAttribute('aria-expanded', 'true');
37354
- this.buttonElement?.setAttribute('aria-controls', popupId);
37355
- }
37356
- initPopupProperties() {
37357
- this.popupRef.content.instance.ctx = this.ctx;
37358
- this.popupRef.content.instance.hostButton = this.host;
37359
- this.popupSubs.add(this.popupRef.content.instance.groupClear.subscribe(() => {
37360
- this.closePopup();
37361
37830
  }));
37362
- this.popupSubs.add(this.popupRef.content.instance.close.subscribe(() => {
37363
- this.closePopup();
37364
- }));
37365
- }
37366
- closePopup() {
37367
- this.buttonElement?.setAttribute('aria-expanded', 'false');
37368
- this.buttonElement?.removeAttribute('aria-controls');
37369
- this.host.selected = false;
37370
- if (this.popupRef) {
37371
- this.popupRef.close();
37372
- this.popupRef = null;
37373
- }
37374
- if (this.popupSubs) {
37375
- this.popupSubs.unsubscribe();
37376
- this.popupSubs = null;
37377
- }
37378
- if (this.removeClickListener) {
37379
- this.removeClickListener();
37380
- this.removeClickListener = null;
37381
- }
37382
- }
37383
- get buttonElement() {
37384
- return this.host.getButton();
37385
- }
37386
- isGroupingApplied(group) {
37387
- return isPresent$1(group) && group.length > 0;
37388
- }
37389
- 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 });
37390
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GroupCommandToolbarDirective, isStandalone: true, selector: "[kendoGridGroupTool]", ngImport: i0 });
37391
- }
37392
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GroupCommandToolbarDirective, decorators: [{
37393
- type: Directive,
37394
- args: [{
37395
- selector: '[kendoGridGroupTool]',
37396
- standalone: true
37397
- }]
37398
- }], ctorParameters: function () { return [{ type: i54.ToolBarButtonComponent }, { type: i2.PopupService }, { type: ContextService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: AdaptiveGridService }]; } });
37399
-
37400
- /**
37401
- * Stores the row and cell highlight state of the Grid.
37402
- *
37403
- * @example
37404
- * ```typescript
37405
- * <kendo-grid kendoGridHighlight="ProductID"></kendo-grid>
37406
- *
37407
- * <kendo-grid [kendoGridHighlight]="myKey"></kendo-grid>
37408
- * ```
37409
- * @remarks
37410
- * Applied to: {@link GridComponent}.
37411
- */
37412
- class HighlightDirective {
37413
- ctx;
37414
- /**
37415
- * Stores the highlighted items keys.
37416
- * @default []
37417
- */
37418
- highlightedKeys = [];
37419
- /**
37420
- * Sets the item key to store in `highlightedKeys`. The Grid uses the row index as the default item key.
37421
- */
37422
- highlightItemKey;
37423
- /**
37424
- * Sets the column key for a data cell. The Grid uses the column index as the default column key.
37425
- */
37426
- highlightColumnKey;
37427
- rowHighlightState = new Set();
37428
- cellHighlightState = new PairSet();
37429
- constructor(ctx) {
37430
- this.ctx = ctx;
37431
- this.ctx.highlightDirective = this;
37432
- }
37433
- ngOnChanges(changes) {
37434
- if (isPresent$1(changes['highlightedKeys'])) {
37435
- this.setState(this.highlightedKeys);
37436
- }
37437
37831
  }
37438
37832
  ngOnDestroy() {
37439
- this.reset();
37440
- this.ctx.highlightDirective = null;
37833
+ super.ngOnDestroy();
37834
+ this.subs.unsubscribe();
37835
+ this.promptOutputs = [];
37441
37836
  }
37442
37837
  /**
37443
37838
  * @hidden
37444
37839
  */
37445
- isRowHighlighted(row) {
37446
- return this.rowHighlightState.has(this.getItemKey(row));
37840
+ onClick() {
37841
+ this.emitOpenClose = true;
37842
+ this.toggleWindow();
37447
37843
  }
37448
37844
  /**
37449
- * @hidden
37845
+ * Toggles the AI Assistant window.
37450
37846
  */
37451
- isCellHighlighted(row, column, colIndex) {
37452
- const highlightItem = this.getHighlightItem(row, column, colIndex);
37453
- return this.cellHighlightState.has(highlightItem.itemKey, highlightItem.columnKey);
37454
- }
37455
- getItemKey(row) {
37456
- if (this.highlightItemKey) {
37457
- if (typeof this.highlightItemKey === "string") {
37458
- return row.data?.[this.highlightItemKey];
37459
- }
37460
- if (typeof this.highlightItemKey === "function") {
37461
- return this.highlightItemKey(row);
37462
- }
37463
- }
37464
- return row.index;
37465
- }
37466
- getHighlightItem(row, col, colIndex) {
37467
- const itemIdentifiers = {};
37468
- itemIdentifiers.itemKey = this.getItemKey(row);
37469
- if (!isPresent$1(col) && !isPresent$1(colIndex)) {
37470
- return itemIdentifiers;
37847
+ toggleWindow() {
37848
+ if (!this.windowRef) {
37849
+ this.openWindow();
37471
37850
  }
37472
- if (this.highlightColumnKey) {
37473
- if (typeof this.highlightColumnKey === "string") {
37474
- itemIdentifiers.columnKey = row.dataItem[this.highlightColumnKey];
37475
- }
37476
- if (typeof this.highlightColumnKey === "function") {
37477
- itemIdentifiers.columnKey = this.highlightColumnKey(col, colIndex);
37478
- }
37851
+ else {
37852
+ this.closeWindow();
37479
37853
  }
37480
- return {
37481
- itemKey: itemIdentifiers.itemKey,
37482
- columnKey: itemIdentifiers.columnKey ? itemIdentifiers.columnKey : colIndex
37483
- };
37484
37854
  }
37485
- setState(highlightedKeys) {
37486
- this.reset();
37487
- if (!highlightedKeys || highlightedKeys.length === 0) {
37488
- return;
37855
+ openWindow() {
37856
+ if (!this.keepOutputHistory) {
37857
+ this.promptOutputs = [];
37489
37858
  }
37490
- const rowHighlights = highlightedKeys.filter(item => !isPresent$1(item.columnKey));
37491
- const cellHighlights = highlightedKeys.filter(item => isPresent$1(item.columnKey));
37492
- if (cellHighlights.length > 0) {
37493
- this.cellHighlightState = new PairSet(cellHighlights, 'itemKey', 'columnKey');
37859
+ const defaultWindowWidth = 437;
37860
+ const rtl = this.ctx.localization.rtl;
37861
+ const defaultWindowSettings = {
37862
+ left: rtl ? this.buttonElement.offsetLeft - (this.aiWindowSettings.width || defaultWindowWidth) : this.buttonElement.offsetLeft + this.buttonElement.offsetWidth,
37863
+ top: this.buttonElement.offsetTop + this.buttonElement.offsetHeight,
37864
+ width: defaultWindowWidth,
37865
+ title: this.ctx.localization.get('aiAssistantWindowTitle'),
37866
+ cssClass: 'k-grid-assistant-window',
37867
+ content: AiAssistantComponent,
37868
+ autoFocusedElement: '.k-input-inner',
37869
+ appendTo: this.ctx.grid.windowContainer
37870
+ };
37871
+ this.aiWindowSettings = {
37872
+ ...defaultWindowSettings,
37873
+ ...this.aiWindowSettings
37874
+ };
37875
+ this.windowRef = this.windowService.open(this.aiWindowSettings);
37876
+ this.windowRef.window.instance.messages = {
37877
+ closeTitle: this.ctx.localization.get('aiAssistantWindowCloseTitle'),
37878
+ maximizeTitle: this.ctx.localization.get('aiAssistantWindowMaximizeTitle'),
37879
+ minimizeTitle: this.ctx.localization.get('aiAssistantWindowMinimizeTitle'),
37880
+ restoreTitle: this.ctx.localization.get('aiAssistantWindowRestoreTitle')
37881
+ };
37882
+ const aiPrompt = this.windowRef.content.instance;
37883
+ aiPrompt.requestUrl = this.requestUrl;
37884
+ aiPrompt.requestOptions = this.requestOptions;
37885
+ aiPrompt.aiToolDirective = this;
37886
+ aiPrompt.disabledGenerateButton = this.aiPromptSettings?.disabledGenerateButton;
37887
+ aiPrompt.streaming = this.aiPromptSettings?.streaming || false;
37888
+ aiPrompt.activeView = this.aiPromptSettings?.activeView || 0;
37889
+ aiPrompt.aiPromptSettings = { ...this.defaultAiPromptSettings, ...this.aiPromptSettings };
37890
+ if (!aiPrompt.aiPromptSettings.promptOutputs) {
37891
+ aiPrompt.aiPromptSettings.promptOutputs = this.promptOutputs;
37494
37892
  }
37495
- if (rowHighlights.length > 0) {
37496
- rowHighlights.forEach(item => {
37497
- this.rowHighlightState.add(item.itemKey);
37893
+ if (this.emitOpenClose) {
37894
+ this.zone.onStable.pipe(take(1)).subscribe(() => {
37895
+ const event = {
37896
+ aiWindow: this.windowRef.window.instance,
37897
+ aiPrompt: this.windowRef.content.instance.aiPrompt
37898
+ };
37899
+ this.open.emit(event);
37900
+ this.emitOpenClose = false;
37498
37901
  });
37499
37902
  }
37903
+ this.subs.add(this.windowRef.window.instance.close.subscribe(() => {
37904
+ this.emitOpenClose = true;
37905
+ this.closeWindow(true);
37906
+ }));
37907
+ this.host.selected = true;
37500
37908
  }
37501
- reset() {
37502
- this.rowHighlightState.clear();
37503
- this.cellHighlightState.clear();
37909
+ closeWindow(focusAnchor = false) {
37910
+ this.windowRef.close();
37911
+ if (this.emitOpenClose) {
37912
+ this.close.emit();
37913
+ this.emitOpenClose = false;
37914
+ }
37915
+ this.windowRef = null;
37916
+ this.buttonElement?.setAttribute('aria-expanded', 'false');
37917
+ this.buttonElement?.removeAttribute('aria-controls');
37918
+ this.host.selected = false;
37919
+ focusAnchor && this.buttonElement?.focus();
37504
37920
  }
37505
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HighlightDirective, deps: [{ token: ContextService }], target: i0.ɵɵFactoryTarget.Directive });
37506
- 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 });
37921
+ 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 });
37922
+ 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 });
37507
37923
  }
37508
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HighlightDirective, decorators: [{
37924
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIAssistantToolbarDirective, decorators: [{
37509
37925
  type: Directive,
37510
37926
  args: [{
37511
- selector: '[kendoGridHighlight]',
37927
+ selector: '[kendoGridAIAssistantTool]',
37512
37928
  standalone: true
37513
37929
  }]
37514
- }], ctorParameters: function () { return [{ type: ContextService }]; }, propDecorators: { highlightedKeys: [{
37930
+ }], ctorParameters: function () { return [{ type: i1$7.WindowService }, { type: i54.ToolBarButtonComponent }, { type: ContextService }, { type: i0.NgZone }, { type: i54.RefreshService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { requestUrl: [{
37515
37931
  type: Input
37516
- }], highlightItemKey: [{
37517
- type: Input,
37518
- args: ["kendoGridHighlight"]
37519
- }], highlightColumnKey: [{
37932
+ }], requestOptions: [{
37933
+ type: Input
37934
+ }], aiWindowSettings: [{
37935
+ type: Input
37936
+ }], aiPromptSettings: [{
37520
37937
  type: Input
37938
+ }], autoClose: [{
37939
+ type: Input
37940
+ }], keepOutputHistory: [{
37941
+ type: Input
37942
+ }], promptRequest: [{
37943
+ type: Output
37944
+ }], cancelRequest: [{
37945
+ type: Output
37946
+ }], responseSuccess: [{
37947
+ type: Output
37948
+ }], responseError: [{
37949
+ type: Output
37950
+ }], close: [{
37951
+ type: Output
37952
+ }], open: [{
37953
+ type: Output
37521
37954
  }] } });
37522
37955
 
37523
37956
  /**
@@ -38098,5 +38531,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
38098
38531
  * Generated bundle index. Do not edit.
38099
38532
  */
38100
38533
 
38101
- export { AIAssistantToolbarDirective, AddCommandDirective, AddCommandToolbarDirective, AfterEqFilterOperatorComponent, AfterFilterOperatorComponent, AutoCompleteFilterCellComponent, BaseFilterCellComponent, BeforeEqFilterOperatorComponent, BeforeFilterOperatorComponent, BooleanFilterCellComponent, BooleanFilterComponent, BooleanFilterMenuComponent, BooleanFilterRadioButtonDirective, BrowserSupportService, CELL_CONTEXT, CancelCommandDirective, CancelCommandToolbarDirective, CellCloseEvent, CellComponent, CellLoadingTemplateDirective, CellSelectionAggregateService, CellSelectionService, CellTemplateDirective, ChangeNotificationService, CheckboxColumnComponent, ColGroupComponent, ColumnBase, ColumnChooserComponent, ColumnChooserToolbarDirective, ColumnComponent, ColumnGroupComponent, ColumnHandleDirective, ColumnInfoService, ColumnListComponent, ColumnLockedChangeEvent, ColumnMenuAutoSizeAllColumnsComponent, ColumnMenuAutoSizeColumnComponent, ColumnMenuChooserComponent, ColumnMenuComponent, ColumnMenuContainerComponent, ColumnMenuFilterComponent, ColumnMenuItemComponent, ColumnMenuItemContentTemplateDirective, ColumnMenuItemDirective, ColumnMenuLockComponent, ColumnMenuPositionComponent, ColumnMenuService, ColumnMenuSortComponent, ColumnMenuStickComponent, ColumnMenuTemplateDirective, ColumnReorderEvent, ColumnReorderService, ColumnResizingService, ColumnStickyChangeEvent, ColumnVisibilityChangeEvent, ColumnsContainer, CommandColumnComponent, ContainsFilterOperatorComponent, ContextService, CustomMessagesComponent, DEFAULT_AI_REQUEST_OPTIONS, DEFAULT_SCROLLER_FACTORY, DataBindingDirective, DateFilterCellComponent, DateFilterComponent, DateFilterMenuComponent, DateFilterMenuInputComponent, DetailCollapseEvent, DetailExpandEvent, DetailTemplateDirective, DetailsService, DoesNotContainFilterOperatorComponent, DomEventsService, DragAndDropService, DragHintService, DropCueService, EditCommandDirective, EditCommandToolbarDirective, EditService as EditServiceClass, EditTemplateDirective, EditingDirectiveBase, EndsWithFilterOperatorComponent, EqualFilterOperatorComponent, ExcelCommandDirective, ExcelCommandToolbarDirective, ExcelComponent, ExcelExportEvent, ExcelModule, ExcelService, ExpandDetailsDirective, ExpandGroupDirective, ExternalEditingDirective, FieldAccessorPipe, FilterCellComponent, FilterCellHostDirective, FilterCellOperatorsComponent, FilterCellTemplateDirective, FilterCellWrapperComponent, FilterCommandToolbarDirective, FilterInputDirective, FilterMenuComponent, FilterMenuContainerComponent, FilterMenuDropDownListDirective, FilterMenuHostDirective, FilterMenuInputWrapperComponent, FilterMenuTemplateDirective, FilterRowComponent, FilterService, FocusRoot, FocusableDirective, FooterComponent, FooterTemplateDirective, GreaterFilterOperatorComponent, GreaterOrEqualToFilterOperatorComponent, GridClipboardDirective, GridComponent, GridModule, GridSpacerComponent, GridTableDirective, GridToolbarAIResponseErrorEvent, GridToolbarAIResponseSuccessEvent, GridToolbarFocusableDirective, GridToolbarNavigationService, GroupCommandToolbarDirective, GroupFooterTemplateDirective, GroupHeaderColumnTemplateDirective, GroupHeaderComponent, GroupHeaderTemplateDirective, GroupInfoService, GroupPanelComponent, GroupsService, HeaderComponent, HeaderTemplateDirective, HighlightDirective, IdService, InCellEditingDirective, IsEmptyFilterOperatorComponent, IsNotEmptyFilterOperatorComponent, IsNotNullFilterOperatorComponent, IsNullFilterOperatorComponent, KENDO_GRID, KENDO_GRID_BODY_EXPORTS, KENDO_GRID_COLUMN_DRAGANDDROP, KENDO_GRID_COLUMN_MENU_DECLARATIONS, KENDO_GRID_COLUMN_MENU_EXPORTS, KENDO_GRID_DECLARATIONS, KENDO_GRID_EXCEL_EXPORT, KENDO_GRID_EXPORTS, KENDO_GRID_FILTER_MENU, KENDO_GRID_FILTER_MENU_EXPORTS, KENDO_GRID_FILTER_OPERATORS, KENDO_GRID_FILTER_ROW, KENDO_GRID_FILTER_ROW_EXPORTS, KENDO_GRID_FILTER_SHARED, KENDO_GRID_FOOTER_EXPORTS, KENDO_GRID_GROUP_EXPORTS, KENDO_GRID_HEADER_EXPORTS, KENDO_GRID_PDF_EXPORT, KENDO_GRID_SHARED, LessFilterOperatorComponent, LessOrEqualToFilterOperatorComponent, ListComponent, LoadingComponent, LoadingTemplateDirective, LocalDataChangesService, LogicalCellDirective, LogicalRowDirective, MenuTabbingService, NavigationService, NoRecordsTemplateDirective, NotEqualFilterOperatorComponent, NumericFilterCellComponent, NumericFilterComponent, NumericFilterMenuComponent, NumericFilterMenuInputComponent, PDFCommandDirective, PDFCommandToolbarDirective, PDFComponent, PDFMarginComponent, PDFModule, PDFService, PDFTemplateDirective, PopupCloseEvent, ReactiveEditingDirective, RedoCommandToolbarDirective, RemoveCommandDirective, RemoveCommandToolbarDirective, ResizableContainerDirective, ResizeService, ResponsiveService, RowDragHandleTemplateDirective, RowDragHintTemplateDirective, RowEditingDirectiveBase, RowReorderColumnComponent, RowReorderService, SaveCommandDirective, SaveCommandToolbarDirective, ScrollRequestService, ScrollSyncService, SelectAllCheckboxDirective, SelectAllToolbarToolComponent, SelectionCheckboxDirective, SelectionDirective, SelectionService, SinglePopupService, SizingOptionsService, Skip, SortCommandToolbarDirective, SortService, SpanColumnComponent, StartsWithFilterOperatorComponent, StatusBarTemplateDirective, StringFilterCellComponent, StringFilterComponent, StringFilterMenuComponent, StringFilterMenuInputComponent, SuspendService, TableBodyComponent, TableDirective, TemplateEditingDirective, ToolbarComponent, ToolbarTemplateDirective, UndoCommandToolbarDirective, UndoRedoDirective, UndoRedoEvent, defaultTrackBy, hasFilterMenu, hasFilterRow, isFilterable };
38534
+ export { AIAssistantToolbarDirective, AddCommandDirective, AddCommandToolbarDirective, AfterEqFilterOperatorComponent, AfterFilterOperatorComponent, AutoCompleteFilterCellComponent, BaseFilterCellComponent, BeforeEqFilterOperatorComponent, BeforeFilterOperatorComponent, BooleanFilterCellComponent, BooleanFilterComponent, BooleanFilterMenuComponent, BooleanFilterRadioButtonDirective, BrowserSupportService, CELL_CONTEXT, CancelCommandDirective, CancelCommandToolbarDirective, CellCloseEvent, CellComponent, CellLoadingTemplateDirective, CellSelectionAggregateService, CellSelectionService, CellTemplateDirective, ChangeNotificationService, CheckboxColumnComponent, ColGroupComponent, ColumnBase, ColumnChooserComponent, ColumnChooserToolbarDirective, ColumnComponent, ColumnGroupComponent, ColumnHandleDirective, ColumnInfoService, ColumnListComponent, ColumnLockedChangeEvent, ColumnMenuAutoSizeAllColumnsComponent, ColumnMenuAutoSizeColumnComponent, ColumnMenuChooserComponent, ColumnMenuComponent, ColumnMenuContainerComponent, ColumnMenuFilterComponent, ColumnMenuItemComponent, ColumnMenuItemContentTemplateDirective, ColumnMenuItemDirective, ColumnMenuLockComponent, ColumnMenuPositionComponent, ColumnMenuService, ColumnMenuSortComponent, ColumnMenuStickComponent, ColumnMenuTemplateDirective, ColumnReorderEvent, ColumnReorderService, ColumnResizingService, ColumnStickyChangeEvent, ColumnVisibilityChangeEvent, ColumnsContainer, CommandColumnComponent, ContainsFilterOperatorComponent, ContextService, CustomMessagesComponent, DEFAULT_AI_REQUEST_OPTIONS, DEFAULT_SCROLLER_FACTORY, DataBindingDirective, DateFilterCellComponent, DateFilterComponent, DateFilterMenuComponent, DateFilterMenuInputComponent, DetailCollapseEvent, DetailExpandEvent, DetailTemplateDirective, DetailsService, DoesNotContainFilterOperatorComponent, DomEventsService, DragAndDropService, DragHintService, DropCueService, EditCommandDirective, EditCommandToolbarDirective, EditService as EditServiceClass, EditTemplateDirective, EditingDirectiveBase, EndsWithFilterOperatorComponent, EqualFilterOperatorComponent, ExcelCommandDirective, ExcelCommandToolbarDirective, ExcelComponent, ExcelExportEvent, ExcelModule, ExcelService, ExpandDetailsDirective, ExpandGroupDirective, ExternalEditingDirective, FieldAccessorPipe, FilterCellComponent, FilterCellHostDirective, FilterCellOperatorsComponent, FilterCellTemplateDirective, FilterCellWrapperComponent, FilterCommandToolbarDirective, FilterInputDirective, FilterMenuComponent, FilterMenuContainerComponent, FilterMenuDropDownListDirective, FilterMenuHostDirective, FilterMenuInputWrapperComponent, FilterMenuTemplateDirective, FilterRowComponent, FilterService, FocusRoot, FocusableDirective, FooterComponent, FooterTemplateDirective, GreaterFilterOperatorComponent, GreaterOrEqualToFilterOperatorComponent, GridClipboardDirective, GridComponent, GridModule, GridSpacerComponent, GridTableDirective, GridToolbarAIResponseErrorEvent, GridToolbarAIResponseSuccessEvent, GridToolbarFocusableDirective, GridToolbarNavigationService, GroupCommandToolbarDirective, GroupFooterTemplateDirective, GroupHeaderColumnTemplateDirective, GroupHeaderComponent, GroupHeaderTemplateDirective, GroupInfoService, GroupPanelComponent, GroupsService, HeaderComponent, HeaderTemplateDirective, HighlightDirective, IdService, InCellEditingDirective, IsEmptyFilterOperatorComponent, IsNotEmptyFilterOperatorComponent, IsNotNullFilterOperatorComponent, IsNullFilterOperatorComponent, KENDO_GRID, KENDO_GRID_BODY_EXPORTS, KENDO_GRID_COLUMN_DRAGANDDROP, KENDO_GRID_COLUMN_MENU_DECLARATIONS, KENDO_GRID_COLUMN_MENU_EXPORTS, KENDO_GRID_DECLARATIONS, KENDO_GRID_EXCEL_EXPORT, KENDO_GRID_EXPORTS, KENDO_GRID_FILTER_MENU, KENDO_GRID_FILTER_MENU_EXPORTS, KENDO_GRID_FILTER_OPERATORS, KENDO_GRID_FILTER_ROW, KENDO_GRID_FILTER_ROW_EXPORTS, KENDO_GRID_FILTER_SHARED, KENDO_GRID_FOOTER_EXPORTS, KENDO_GRID_GROUP_EXPORTS, KENDO_GRID_HEADER_EXPORTS, KENDO_GRID_PDF_EXPORT, KENDO_GRID_SHARED, LessFilterOperatorComponent, LessOrEqualToFilterOperatorComponent, ListComponent, LoadingComponent, LoadingTemplateDirective, LocalDataChangesService, LogicalCellDirective, LogicalRowDirective, MenuTabbingService, MultiCheckboxFilterComponent, NavigationService, NoRecordsTemplateDirective, NotEqualFilterOperatorComponent, NumericFilterCellComponent, NumericFilterComponent, NumericFilterMenuComponent, NumericFilterMenuInputComponent, PDFCommandDirective, PDFCommandToolbarDirective, PDFComponent, PDFMarginComponent, PDFModule, PDFService, PDFTemplateDirective, PopupCloseEvent, ReactiveEditingDirective, RedoCommandToolbarDirective, RemoveCommandDirective, RemoveCommandToolbarDirective, ResizableContainerDirective, ResizeService, ResponsiveService, RowDragHandleTemplateDirective, RowDragHintTemplateDirective, RowEditingDirectiveBase, RowReorderColumnComponent, RowReorderService, SaveCommandDirective, SaveCommandToolbarDirective, ScrollRequestService, ScrollSyncService, SelectAllCheckboxDirective, SelectAllToolbarToolComponent, SelectionCheckboxDirective, SelectionDirective, SelectionService, SinglePopupService, SizingOptionsService, Skip, SortCommandToolbarDirective, SortService, SpanColumnComponent, StartsWithFilterOperatorComponent, StatusBarTemplateDirective, StringFilterCellComponent, StringFilterComponent, StringFilterMenuComponent, StringFilterMenuInputComponent, SuspendService, TableBodyComponent, TableDirective, TemplateEditingDirective, ToolbarComponent, ToolbarTemplateDirective, UndoCommandToolbarDirective, UndoRedoDirective, UndoRedoEvent, defaultTrackBy, hasFilterMenu, hasFilterRow, isFilterable };
38102
38535