From e318c7ad128076dd26527679b2045667c74e9ce6 Mon Sep 17 00:00:00 2001 From: Alyar <> Date: Thu, 20 Aug 2026 16:00:21 +0400 Subject: [PATCH 1/4] Remove _adaptiveColumnsController from dataController --- .../js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts | 3 +++ .../grids/grid_core/data_controller/data_controller.ts | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts index d673a9ecf785..036c38325d2b 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts @@ -1190,9 +1190,12 @@ const data = ( ) => class AdaptivityDataControllerExtender extends Base { private _adaptiveExpandedKey: any; + protected _adaptiveColumnsController!: AdaptiveColumnsController; + public init() { super.init(); this._adaptiveExpandedKey = undefined; + this._adaptiveColumnsController = this.getController('adaptiveColumns'); } protected _processItems(items: RawItemData[], change: DataChange): ProcessedItem[] { diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_controller/data_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/data_controller/data_controller.ts index a842133588e6..36b1d090e1b5 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_controller/data_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_controller/data_controller.ts @@ -126,8 +126,6 @@ export class DataController extends DataHelperMixin(modules.Controller) { // TODO public controller public _columnsController!: Controllers['columns']; - protected _adaptiveColumnsController!: Controllers['adaptiveColumns']; - // TODO public controller public _rowsScrollController?: VirtualScrollController | null; @@ -151,7 +149,6 @@ export class DataController extends DataHelperMixin(modules.Controller) { this._items = []; this._cachedProcessedItems = null; this._columnsController = this.getController('columns'); - this._adaptiveColumnsController = this.getController('adaptiveColumns'); this._editingController = this.getController('editing'); this._filterSyncController = this.getController('filterSync'); this._keyboardNavigationController = this.getController('keyboardNavigation'); From 538c77ab7e6109a4fc92da8829e7a92ba75ab759 Mon Sep 17 00:00:00 2001 From: Alyar <> Date: Thu, 20 Aug 2026 16:03:52 +0400 Subject: [PATCH 2/4] Rename _adaptiveColumnsController to adaptiveColumnsController --- .../grid_core/adaptivity/m_adaptivity.ts | 58 +++++++++---------- .../grids/grid_core/editing/m_editing.ts | 4 +- .../m_keyboard_navigation.ts | 6 +- .../sticky_columns/m_sticky_columns.ts | 2 +- .../grids/grid_core/views/m_columns_view.ts | 4 +- .../grids/grid_core/views/m_grid_view.ts | 4 +- .../adaptiveColumns.tests.js | 4 +- 7 files changed, 41 insertions(+), 41 deletions(-) diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts index 036c38325d2b..d689f5a1c221 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts @@ -907,7 +907,7 @@ const rowsView = ( if (options.rowType === ADAPTIVE_ROW_TYPE && column.command === 'detail') { return function (container, options) { - that._adaptiveColumnsController.createFormByHiddenColumns($(container), options); + that.adaptiveColumnsController.createFormByHiddenColumns($(container), options); }; } return super._getCellTemplate(options); @@ -926,7 +926,7 @@ const rowsView = ( protected _renderCells($row, options) { super._renderCells($row, options); - const adaptiveColumnsController = this._adaptiveColumnsController; + const { adaptiveColumnsController } = this; const hidingColumnsQueueLength = adaptiveColumnsController.getHidingColumnsQueue().length; const hiddenColumnsLength = adaptiveColumnsController.getHiddenColumns().length; @@ -961,7 +961,7 @@ const rowsView = ( const item = this._dataController.items()[cellPosition?.rowIndex]; if (item?.rowType === ADAPTIVE_ROW_TYPE) { - const $adaptiveDetailItems = this._adaptiveColumnsController.getAdaptiveDetailItems(); + const $adaptiveDetailItems = this.adaptiveColumnsController.getAdaptiveDetailItems(); return super.getCell(cellPosition, rows, $adaptiveDetailItems); } @@ -972,7 +972,7 @@ const rowsView = ( const item = this._dataController.items()[rowIndex]; if (item && item.rowType === ADAPTIVE_ROW_TYPE) { - return this._adaptiveColumnsController.getItemContentByColumnIndex(columnIdentifier); + return this.adaptiveColumnsController.getItemContentByColumnIndex(columnIdentifier); } return super._getCellElement.apply(this, arguments as any); } @@ -1081,13 +1081,13 @@ const editing = ( } protected _beforeUpdateItems(rowIndices, rowIndex) { - if (!this._adaptiveColumnsController.isFormOrPopupEditMode() && this._adaptiveColumnsController.hasHiddenColumns()) { + if (!this.adaptiveColumnsController.isFormOrPopupEditMode() && this.adaptiveColumnsController.hasHiddenColumns()) { const items = this._dataController.items(); const item = items[rowIndex]; // @ts-expect-error const oldExpandRowIndex = gridCoreUtils.getIndexByKey(this._dataController.adaptiveExpandedKey(), items); - this._isForceRowAdaptiveExpand = !this._adaptiveColumnsController.hasAdaptiveDetailRowExpanded(); + this._isForceRowAdaptiveExpand = !this.adaptiveColumnsController.hasAdaptiveDetailRowExpanded(); if (oldExpandRowIndex >= 0) { rowIndices.push(oldExpandRowIndex + 1); @@ -1102,22 +1102,22 @@ const editing = ( protected _afterInsertRow(key) { super._afterInsertRow.apply(this, arguments as any); - if (this._adaptiveColumnsController.hasHiddenColumns()) { + if (this.adaptiveColumnsController.hasHiddenColumns()) { // @ts-expect-error - this._adaptiveColumnsController.toggleExpandAdaptiveDetailRow(key, this.isRowEditMode()); + this.adaptiveColumnsController.toggleExpandAdaptiveDetailRow(key, this.isRowEditMode()); this._isForceRowAdaptiveExpand = true; } } private _collapseAdaptiveDetailRow() { if (this._isRowEditMode() && this._isForceRowAdaptiveExpand) { - this._adaptiveColumnsController.collapseAdaptiveDetailRow(); + this.adaptiveColumnsController.collapseAdaptiveDetailRow(); this._isForceRowAdaptiveExpand = false; } } private _cancelEditAdaptiveDetailRow() { - if (this._adaptiveColumnsController.hasHiddenColumns()) { + if (this.adaptiveColumnsController.hasHiddenColumns()) { this._collapseAdaptiveDetailRow(); } } @@ -1126,7 +1126,7 @@ const editing = ( super._afterSaveEditData.apply(this, arguments as any); // @ts-expect-error const deferred = new Deferred(); - if (this._isRowEditMode() && this._adaptiveColumnsController.hasHiddenColumns()) { + if (this._isRowEditMode() && this.adaptiveColumnsController.hasHiddenColumns()) { when(this._validatingController.validate(true)).done((isValid) => { if (isValid) { this._cancelEditAdaptiveDetailRow(); @@ -1147,7 +1147,7 @@ const editing = ( protected _getRowIndicesForCascadeUpdating(row) { const rowIndices = super._getRowIndicesForCascadeUpdating.apply(this, arguments as any); - if (this._adaptiveColumnsController.isAdaptiveDetailRowExpanded(row.key)) { + if (this.adaptiveColumnsController.isAdaptiveDetailRowExpanded(row.key)) { rowIndices.push(row.rowType === ADAPTIVE_ROW_TYPE ? row.rowIndex - 1 : row.rowIndex + 1); } @@ -1167,8 +1167,8 @@ const editing = ( } public editRow(rowIndex) { - if (this._adaptiveColumnsController.isFormOrPopupEditMode()) { - this._adaptiveColumnsController.collapseAdaptiveDetailRow(); + if (this.adaptiveColumnsController.isFormOrPopupEditMode()) { + this.adaptiveColumnsController.collapseAdaptiveDetailRow(); } return super.editRow(rowIndex); @@ -1177,8 +1177,8 @@ const editing = ( protected deleteRow(rowIndex) { const rowKey = this._dataController.getKeyByRowIndex(rowIndex); - if (this.getEditMode() === EDIT_MODE_BATCH && this._adaptiveColumnsController.isAdaptiveDetailRowExpanded(rowKey)) { - this._adaptiveColumnsController.collapseAdaptiveDetailRow(); + if (this.getEditMode() === EDIT_MODE_BATCH && this.adaptiveColumnsController.isAdaptiveDetailRowExpanded(rowKey)) { + this.adaptiveColumnsController.collapseAdaptiveDetailRow(); } super.deleteRow(rowIndex); @@ -1190,12 +1190,12 @@ const data = ( ) => class AdaptivityDataControllerExtender extends Base { private _adaptiveExpandedKey: any; - protected _adaptiveColumnsController!: AdaptiveColumnsController; + protected adaptiveColumnsController!: AdaptiveColumnsController; public init() { super.init(); this._adaptiveExpandedKey = undefined; - this._adaptiveColumnsController = this.getController('adaptiveColumns'); + this.adaptiveColumnsController = this.getController('adaptiveColumns'); } protected _processItems(items: RawItemData[], change: DataChange): ProcessedItem[] { @@ -1233,7 +1233,7 @@ const data = ( // @ts-expect-error const rowIndices = super._getRowIndicesForExpand.apply(this, arguments); - if (this._adaptiveColumnsController.isAdaptiveDetailRowExpanded(key)) { + if (this.adaptiveColumnsController.isAdaptiveDetailRowExpanded(key)) { const lastRowIndex = rowIndices[rowIndices.length - 1]; rowIndices.push(lastRowIndex + 1); } @@ -1278,8 +1278,8 @@ const data = ( rowIndices: [oldExpandLoadedRowIndex - rowIndexDelta, newExpandLoadedRowIndex - rowIndexDelta], }); - this._adaptiveColumnsController.updateCommandAdaptiveAriaLabel(key, COLLAPSE_ARIA_NAME); - this._adaptiveColumnsController.updateCommandAdaptiveAriaLabel(oldKey, EXPAND_ARIA_NAME); + this.adaptiveColumnsController.updateCommandAdaptiveAriaLabel(key, COLLAPSE_ARIA_NAME); + this.adaptiveColumnsController.updateCommandAdaptiveAriaLabel(oldKey, EXPAND_ARIA_NAME); } }; @@ -1305,11 +1305,11 @@ const editorFactory = ( const columns = ( Base: ModuleType, ) => class AdaptivityColumnsExtender extends Base { - private _adaptiveColumnsController!: AdaptiveColumnsController; + private adaptiveColumnsController!: AdaptiveColumnsController; public init(isApplyingUserState?: boolean): void { super.init(isApplyingUserState); - this._adaptiveColumnsController = this.getController('adaptiveColumns'); + this.adaptiveColumnsController = this.getController('adaptiveColumns'); } protected _isColumnVisible(column) { @@ -1323,7 +1323,7 @@ const columns = ( public isAdaptiveHiddenColumn(column: Column): boolean { return super.isAdaptiveHiddenColumn(column) - || this._adaptiveColumnsController.isColumnHidden(column); + || this.adaptiveColumnsController.isColumnHidden(column); } }; @@ -1358,11 +1358,11 @@ const resizing = (Base: ModuleType) => class AdaptivityResiz protected _needBestFit() { // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - return super._needBestFit() || !!this._adaptiveColumnsController.getHidingColumnsQueue().length; + return super._needBestFit() || !!this.adaptiveColumnsController.getHidingColumnsQueue().length; } protected _correctColumnWidths(resultWidths: (number | string | undefined)[], visibleColumns: Column[]): boolean { - const adaptiveController = this._adaptiveColumnsController; + const adaptiveController = this.adaptiveColumnsController; const oldHiddenColumns = adaptiveController.getHiddenColumns(); const hidingColumnsQueue = adaptiveController.updateHidingQueue(this._columnsController.getColumns()); @@ -1386,13 +1386,13 @@ const resizing = (Base: ModuleType) => class AdaptivityResiz } protected _toggleBestFitMode(isBestFit) { - this._adaptiveColumnsController._toggleGroupAdaptiveRowVisibility(isBestFit); - isBestFit && this._adaptiveColumnsController._showHiddenColumns(); + this.adaptiveColumnsController._toggleGroupAdaptiveRowVisibility(isBestFit); + isBestFit && this.adaptiveColumnsController._showHiddenColumns(); super._toggleBestFitMode(isBestFit); } protected _needStretch() { - const adaptiveColumnsController = this._adaptiveColumnsController; + const { adaptiveColumnsController } = this; return super._needStretch.apply(this, arguments as any) || adaptiveColumnsController.getHidingColumnsQueue().length || adaptiveColumnsController.hasHiddenColumns(); } }; diff --git a/packages/devextreme/js/__internal/grids/grid_core/editing/m_editing.ts b/packages/devextreme/js/__internal/grids/grid_core/editing/m_editing.ts index 679732e7d44f..61c8954c733d 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/editing/m_editing.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/editing/m_editing.ts @@ -116,7 +116,7 @@ class EditingControllerImpl extends modules.ViewController { protected _dataController!: Controllers['data']; - protected _adaptiveColumnsController!: Controllers['adaptiveColumns']; + protected adaptiveColumnsController!: Controllers['adaptiveColumns']; protected _validatingController!: Controllers['validating']; @@ -169,7 +169,7 @@ class EditingControllerImpl extends modules.ViewController { public init() { this._columnsController = this.getController('columns'); this._dataController = this.getController('data'); - this._adaptiveColumnsController = this.getController('adaptiveColumns'); + this.adaptiveColumnsController = this.getController('adaptiveColumns'); this._validatingController = this.getController('validating'); this._editorFactoryController = this.getController('editorFactory'); this._focusController = this.getController('focus'); diff --git a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts index 3a761c81cec1..499bc442c7d0 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/keyboard_navigation/m_keyboard_navigation.ts @@ -141,7 +141,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo private _focusController!: Controllers['focus']; - private _adaptiveColumnsController!: Controllers['adaptiveColumns']; + private adaptiveColumnsController!: Controllers['adaptiveColumns']; private _columnResizerController!: Controllers['columnsResizer']; @@ -156,7 +156,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo this._editingController = this.getController('editing'); this._editorFactory = this.getController('editorFactory'); this._focusController = this.getController('focus'); - this._adaptiveColumnsController = this.getController('adaptiveColumns'); + this.adaptiveColumnsController = this.getController('adaptiveColumns'); this._columnResizerController = this.getController('columnsResizer'); this._rowsView = this.getView('rowsView'); this.searchPanel = this.getController('searchPanel'); @@ -1250,7 +1250,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo (this._dataController as any).changeRowExpand(key); } } else if (needExpandAdaptiveRow) { - this._adaptiveColumnsController.toggleExpandAdaptiveDetailRow(key); + this.adaptiveColumnsController.toggleExpandAdaptiveDetailRow(key); this._updateFocusedCellPosition($cell); } else if (this.getMasterDetailCell($cell)?.is($cell)) { diff --git a/packages/devextreme/js/__internal/grids/grid_core/sticky_columns/m_sticky_columns.ts b/packages/devextreme/js/__internal/grids/grid_core/sticky_columns/m_sticky_columns.ts index 613e6b90344d..60e76e3f355e 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/sticky_columns/m_sticky_columns.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/sticky_columns/m_sticky_columns.ts @@ -244,7 +244,7 @@ const baseStickyColumns = >(Base: T) => class protected _resizeCore(): void { const hasStickyColumns = this.hasStickyColumns(); - const hasHidingColumnsQueue = !!this._adaptiveColumnsController + const hasHidingColumnsQueue = !!this.adaptiveColumnsController ?.getHidingColumnsQueue()?.length; super._resizeCore.apply(this); diff --git a/packages/devextreme/js/__internal/grids/grid_core/views/m_columns_view.ts b/packages/devextreme/js/__internal/grids/grid_core/views/m_columns_view.ts index f19a2f026b30..9dcff6ee5c59 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/views/m_columns_view.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/views/m_columns_view.ts @@ -193,7 +193,7 @@ export class ColumnsView extends ColumnStateMixin(modules.View) { protected _dataController!: DataController; - protected _adaptiveColumnsController!: AdaptiveColumnsController; + protected adaptiveColumnsController!: AdaptiveColumnsController; protected _columnChooserController!: ColumnChooserController; @@ -207,7 +207,7 @@ export class ColumnsView extends ColumnStateMixin(modules.View) { this._scrollLeft = -1; this._columnsController = this.getController('columns'); this._dataController = this.getController('data'); - this._adaptiveColumnsController = this.getController('adaptiveColumns'); + this.adaptiveColumnsController = this.getController('adaptiveColumns'); this._columnChooserController = this.getController('columnChooser'); this._editorFactoryController = this.getController('editorFactory'); this._selectionController = this.getController('selection'); diff --git a/packages/devextreme/js/__internal/grids/grid_core/views/m_grid_view.ts b/packages/devextreme/js/__internal/grids/grid_core/views/m_grid_view.ts index 62f39e8c4836..2a671b7f1434 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/views/m_grid_view.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/views/m_grid_view.ts @@ -115,7 +115,7 @@ export class ResizingController extends modules.ViewController { private _lastHeight: any; - protected _adaptiveColumnsController!: AdaptiveColumnsController; + protected adaptiveColumnsController!: AdaptiveColumnsController; private _editorFactoryController!: EditorFactory; @@ -132,7 +132,7 @@ export class ResizingController extends modules.ViewController { this._dataController = this.getController('data'); this._columnsController = this.getController('columns'); this._columnHeadersView = this.getView('columnHeadersView'); - this._adaptiveColumnsController = this.getController('adaptiveColumns'); + this.adaptiveColumnsController = this.getController('adaptiveColumns'); this._editorFactoryController = this.getController('editorFactory'); this._footerView = this.getView('footerView'); this._rowsView = this.getView('rowsView'); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/adaptiveColumns.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/adaptiveColumns.tests.js index 62f7c4e1a833..66db500c82ad 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/adaptiveColumns.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/adaptiveColumns.tests.js @@ -4394,7 +4394,7 @@ QUnit.module('Validation', { this.clock.tick(10); // assert - assert.equal(this.rowsView._adaptiveColumnsController.getHiddenColumns().length, 0, 'has not hidden adaptive columns'); + assert.equal(this.rowsView.adaptiveColumnsController.getHiddenColumns().length, 0, 'has not hidden adaptive columns'); }); QUnit.testInActiveWindow('If columns has the width property then columns width before hiding should be equal to the width of the columns', function(assert) { @@ -4419,7 +4419,7 @@ QUnit.module('Validation', { this.clock.tick(10); // assert - assert.equal(this.rowsView._adaptiveColumnsController.getHiddenColumns().length, 0, 'has not hidden adaptive columns'); + assert.equal(this.rowsView.adaptiveColumnsController.getHiddenColumns().length, 0, 'has not hidden adaptive columns'); }); QUnit.test('The onRowValidating event is not called twice if isValid is set to \'false\'', function(assert) { From 0728b5837b386e66b074f94ecf3292ab01ac7ef7 Mon Sep 17 00:00:00 2001 From: Alyar <> Date: Thu, 20 Aug 2026 18:17:41 +0400 Subject: [PATCH 3/4] Grids: move adaptivity extenders to separate files --- .../module_not_extended/adaptivity.ts | 2 +- .../grid_core/adaptivity/adaptivity_module.ts | 41 ++ .../grids/grid_core/adaptivity/const.ts | 31 + .../extenders/adaptivity_columns.ts | 33 + .../extenders/adaptivity_columns_resizer.ts | 35 + .../extenders/adaptivity_data_controller.ts | 121 +++ .../extenders/adaptivity_dragging_header.ts | 21 + .../extenders/adaptivity_editing.ts | 151 ++++ .../extenders/adaptivity_editor_factory.ts | 25 + .../adaptivity/extenders/adaptivity_export.ts | 15 + .../adaptivity_headers_keyboard_navigation.ts | 45 ++ .../adaptivity_keyboard_navigation.ts | 62 ++ .../adaptivity_resizing_controller.ts | 83 +++ .../extenders/adaptivity_rows_view.ts | 125 ++++ .../grid_core/adaptivity/m_adaptivity.ts | 688 +----------------- .../module_not_extended/adaptivity.ts | 2 +- 16 files changed, 816 insertions(+), 664 deletions(-) create mode 100644 packages/devextreme/js/__internal/grids/grid_core/adaptivity/adaptivity_module.ts create mode 100644 packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_columns.ts create mode 100644 packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_columns_resizer.ts create mode 100644 packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_data_controller.ts create mode 100644 packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_dragging_header.ts create mode 100644 packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_editing.ts create mode 100644 packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_editor_factory.ts create mode 100644 packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_export.ts create mode 100644 packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_headers_keyboard_navigation.ts create mode 100644 packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_keyboard_navigation.ts create mode 100644 packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_resizing_controller.ts create mode 100644 packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_rows_view.ts diff --git a/packages/devextreme/js/__internal/grids/data_grid/module_not_extended/adaptivity.ts b/packages/devextreme/js/__internal/grids/data_grid/module_not_extended/adaptivity.ts index 4999981811cb..b8ca0a2f63e3 100644 --- a/packages/devextreme/js/__internal/grids/data_grid/module_not_extended/adaptivity.ts +++ b/packages/devextreme/js/__internal/grids/data_grid/module_not_extended/adaptivity.ts @@ -1,4 +1,4 @@ -import { adaptivityModule } from '@ts/grids/grid_core/adaptivity/m_adaptivity'; +import { adaptivityModule } from '@ts/grids/grid_core/adaptivity/adaptivity_module'; import gridCore from '../m_core'; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/adaptivity_module.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/adaptivity_module.ts new file mode 100644 index 000000000000..4dd174693cc0 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/adaptivity_module.ts @@ -0,0 +1,41 @@ +import type { Module } from '../m_types'; +import { adaptivityColumnsExtender } from './extenders/adaptivity_columns'; +import { adaptivityColumnsResizerExtender } from './extenders/adaptivity_columns_resizer'; +import { adaptivityDataControllerExtender } from './extenders/adaptivity_data_controller'; +import { adaptivityDraggingHeaderExtender } from './extenders/adaptivity_dragging_header'; +import { adaptivityEditingExtender } from './extenders/adaptivity_editing'; +import { adaptivityEditorFactoryExtender } from './extenders/adaptivity_editor_factory'; +import { adaptivityExportExtender } from './extenders/adaptivity_export'; +import { adaptivityHeadersKeyboardNavigationExtender } from './extenders/adaptivity_headers_keyboard_navigation'; +import { adaptivityKeyboardNavigationExtender } from './extenders/adaptivity_keyboard_navigation'; +import { adaptivityResizingControllerExtender } from './extenders/adaptivity_resizing_controller'; +import { adaptivityRowsViewExtender } from './extenders/adaptivity_rows_view'; +import { AdaptiveColumnsController } from './m_adaptivity'; + +export const adaptivityModule: Module = { + defaultOptions() { + return { + columnHidingEnabled: false, + }; + }, + controllers: { + adaptiveColumns: AdaptiveColumnsController, + }, + extenders: { + views: { + rowsView: adaptivityRowsViewExtender, + }, + controllers: { + export: adaptivityExportExtender, + columnsResizer: adaptivityColumnsResizerExtender, + draggingHeader: adaptivityDraggingHeaderExtender, + editing: adaptivityEditingExtender, + resizing: adaptivityResizingControllerExtender, + data: adaptivityDataControllerExtender, + editorFactory: adaptivityEditorFactoryExtender, + columns: adaptivityColumnsExtender, + keyboardNavigation: adaptivityKeyboardNavigationExtender, + headersKeyboardNavigation: adaptivityHeadersKeyboardNavigationExtender, + }, + }, +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/const.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/const.ts index b77e371f34aa..22be9f8267a4 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/const.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/const.ts @@ -1 +1,32 @@ +export const COLUMN_HEADERS_VIEW = 'columnHeadersView' as const; +export const ROWS_VIEW = 'rowsView' as const; +export const FOOTER_VIEW = 'footerView' as const; +export const COLUMN_VIEWS = [COLUMN_HEADERS_VIEW, ROWS_VIEW, FOOTER_VIEW] as const; + +export const ADAPTIVE_NAMESPACE = 'dxDataGridAdaptivity'; export const HIDDEN_COLUMNS_WIDTH = 'adaptiveHidden'; +export const ADAPTIVE_ROW_TYPE = 'detailAdaptive'; + +export const FORM_ITEM_CONTENT_CLASS = 'dx-field-item-content'; +export const FORM_ITEM_MODIFIED = 'dx-item-modified'; + +export const HIDDEN_COLUMN_CLASS = 'hidden-column'; +export const ADAPTIVE_COLUMN_BUTTON_CLASS = 'adaptive-more'; +export const ADAPTIVE_COLUMN_NAME_CLASS = 'dx-command-adaptive'; +export const COMMAND_ADAPTIVE_HIDDEN_CLASS = 'dx-command-adaptive-hidden'; +export const ADAPTIVE_DETAIL_ROW_CLASS = 'dx-adaptive-detail-row'; +export const ADAPTIVE_ITEM_TEXT_CLASS = 'dx-adaptive-item-text'; +export const MASTER_DETAIL_CELL_CLASS = 'dx-master-detail-cell'; +export const LAST_DATA_CELL_CLASS = 'dx-last-data-cell'; +export const ADAPTIVE_COLUMN_NAME = 'adaptive'; +export const EDIT_MODE_BATCH = 'batch'; +export const EDIT_MODE_ROW = 'row'; +export const EDIT_MODE_FORM = 'form'; +export const EDIT_MODE_POPUP = 'popup'; +export const REVERT_TOOLTIP_CLASS = 'revert-tooltip'; +export const GROUP_CELL_CLASS = 'dx-group-cell'; +export const GROUP_ROW_CLASS = 'dx-group-row'; + +export const EXPAND_ARIA_NAME = 'dxDataGrid-ariaAdaptiveExpand'; +export const COLLAPSE_ARIA_NAME = 'dxDataGrid-ariaAdaptiveCollapse'; +export const LEGACY_SCROLLING_MODE = 'scrolling.legacyMode'; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_columns.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_columns.ts new file mode 100644 index 000000000000..6fc817b17aea --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_columns.ts @@ -0,0 +1,33 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +import type { ColumnsController } from '@ts/grids/grid_core/columns_controller/m_columns_controller'; +import type { Column } from '@ts/grids/grid_core/columns_controller/types'; +import type { ModuleType } from '@ts/grids/grid_core/m_types'; + +import { HIDDEN_COLUMNS_WIDTH } from '../const'; +import type { AdaptiveColumnsController } from '../m_adaptivity'; + +export const adaptivityColumnsExtender = ( + Base: ModuleType, +): ModuleType => class AdaptivityColumnsExtender extends Base { + private adaptiveColumnsController!: AdaptiveColumnsController; + + public init(isApplyingUserState?: boolean): void { + super.init(isApplyingUserState); + this.adaptiveColumnsController = this.getController('adaptiveColumns'); + } + + protected _isColumnVisible(column) { + return super._isColumnVisible(column) && !column.adaptiveHidden; + } + + public getVisibleDataColumnsByBandColumn(bandColumnIndex: number) { + return super.getVisibleDataColumnsByBandColumn(bandColumnIndex) + .filter((column) => column.visibleWidth !== HIDDEN_COLUMNS_WIDTH); + } + + public isAdaptiveHiddenColumn(column: Column): boolean { + return super.isAdaptiveHiddenColumn(column) + || this.adaptiveColumnsController.isColumnHidden(column); + } +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_columns_resizer.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_columns_resizer.ts new file mode 100644 index 000000000000..1a4dc43e84da --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_columns_resizer.ts @@ -0,0 +1,35 @@ +/* eslint-disable @stylistic/max-len */ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable no-plusplus */ +import type { dxElementWrapper } from '@js/core/renderer'; +import type { ColumnsResizerViewController } from '@ts/grids/grid_core/columns_resizing_reordering/m_columns_resizing_reordering'; +import type { ModuleType } from '@ts/grids/grid_core/m_types'; + +import { HIDDEN_COLUMNS_WIDTH } from '../const'; + +export const adaptivityColumnsResizerExtender = ( + Base: ModuleType, +): ModuleType => class AdaptivityColumnsResizerExtender extends Base { + protected _pointCreated(point, columns, cells?: dxElementWrapper) { + const result = super._pointCreated(point, columns, cells); + const currentColumn = columns[point.columnIndex] || {}; + const nextColumnIndex = this._getNextColumnIndex(point.columnIndex); + const nextColumn = columns[nextColumnIndex] || {}; + const hasHiddenColumnsOnly = nextColumnIndex !== point.columnIndex + 1 && nextColumn.command; + const hasAdaptiveHiddenWidth = currentColumn.visibleWidth === HIDDEN_COLUMNS_WIDTH || hasHiddenColumnsOnly; + + return result || hasAdaptiveHiddenWidth; + } + + protected _getNextColumnIndex(currentColumnIndex) { + const visibleColumns = this._columnsController.getVisibleColumns(); + let index = super._getNextColumnIndex(currentColumnIndex); + + while (visibleColumns[index]?.visibleWidth === HIDDEN_COLUMNS_WIDTH) { + index++; + } + + return index; + } +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_data_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_data_controller.ts new file mode 100644 index 000000000000..f36e76b8a9bb --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_data_controller.ts @@ -0,0 +1,121 @@ +/* eslint-disable @stylistic/max-len */ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-this-alias */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable consistent-return */ +/* eslint-disable no-param-reassign */ +/* eslint-disable no-plusplus */ +/* eslint-disable prefer-rest-params */ +import { isDefined } from '@js/core/utils/type'; +import type { DataController } from '@ts/grids/grid_core/data_controller/data_controller'; +import type { DataChange, ProcessedItem } from '@ts/grids/grid_core/data_controller/types'; +import type { RawItemData } from '@ts/grids/grid_core/data_source_adapter/types'; +import type { ModuleType } from '@ts/grids/grid_core/m_types'; +import gridCoreUtils from '@ts/grids/grid_core/m_utils'; + +import { + ADAPTIVE_ROW_TYPE, + COLLAPSE_ARIA_NAME, + EXPAND_ARIA_NAME, + LEGACY_SCROLLING_MODE, +} from '../const'; +import type { AdaptiveColumnsController } from '../m_adaptivity'; + +export const adaptivityDataControllerExtender = ( + Base: ModuleType, +): ModuleType => class AdaptivityDataControllerExtender extends Base { + private _adaptiveExpandedKey: any; + + protected adaptiveColumnsController!: AdaptiveColumnsController; + + public init() { + super.init(); + this._adaptiveExpandedKey = undefined; + this.adaptiveColumnsController = this.getController('adaptiveColumns'); + } + + protected _processItems(items: RawItemData[], change: DataChange): ProcessedItem[] { + const processedItems = super._processItems(items, change); + const { changeType } = change; + + if ((changeType === 'loadingAll') || !isDefined(this._adaptiveExpandedKey)) { + return processedItems; + } + + const expandRowIndex = gridCoreUtils.getIndexByKey(this._adaptiveExpandedKey, processedItems); + const newMode = this.option(LEGACY_SCROLLING_MODE) === false; + + if (expandRowIndex >= 0) { + const item = processedItems[expandRowIndex]; + processedItems.splice(expandRowIndex + 1, 0, { + visible: true, + rowType: ADAPTIVE_ROW_TYPE, + key: item.key, + data: item.data, + // @ts-expect-error treelist specific field + node: item.node, + modifiedValues: item.modifiedValues, + isNewRow: item.isNewRow, + values: item.values, + }); + } else if (changeType === 'refresh' && !(newMode && change.repaintChangesOnly)) { + this._adaptiveExpandedKey = undefined; + } + + return processedItems; + } + + private _getRowIndicesForExpand(key) { + // @ts-expect-error + const rowIndices = super._getRowIndicesForExpand.apply(this, arguments); + + if (this.adaptiveColumnsController.isAdaptiveDetailRowExpanded(key)) { + const lastRowIndex = rowIndices[rowIndices.length - 1]; + rowIndices.push(lastRowIndex + 1); + } + + return rowIndices; + } + + private adaptiveExpandedKey(value) { + if (isDefined(value)) { + this._adaptiveExpandedKey = value; + } else { + return this._adaptiveExpandedKey; + } + } + + private toggleExpandAdaptiveDetailRow(key, alwaysExpanded) { + const that = this; + + let oldExpandLoadedRowIndex = gridCoreUtils.getIndexByKey(that._adaptiveExpandedKey, that._items); + let newExpandLoadedRowIndex = gridCoreUtils.getIndexByKey(key, that._items); + + if (oldExpandLoadedRowIndex >= 0 && oldExpandLoadedRowIndex === newExpandLoadedRowIndex && !alwaysExpanded) { + key = undefined; + newExpandLoadedRowIndex = -1; + } + + const oldKey = that._adaptiveExpandedKey; + that._adaptiveExpandedKey = key; + + if (oldExpandLoadedRowIndex >= 0) { + oldExpandLoadedRowIndex++; + } + if (newExpandLoadedRowIndex >= 0) { + newExpandLoadedRowIndex++; + } + + const rowIndexDelta = that.getRowIndexDelta(); + + that.updateItems({ + allowInvisibleRowIndices: true, + changeType: 'update', + rowIndices: [oldExpandLoadedRowIndex - rowIndexDelta, newExpandLoadedRowIndex - rowIndexDelta], + }); + + this.adaptiveColumnsController.updateCommandAdaptiveAriaLabel(key, COLLAPSE_ARIA_NAME); + this.adaptiveColumnsController.updateCommandAdaptiveAriaLabel(oldKey, EXPAND_ARIA_NAME); + } +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_dragging_header.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_dragging_header.ts new file mode 100644 index 000000000000..29b10bf38af5 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_dragging_header.ts @@ -0,0 +1,21 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +import type { DraggingHeaderViewController } from '@ts/grids/grid_core/columns_resizing_reordering/m_columns_resizing_reordering'; +import type { ModuleType } from '@ts/grids/grid_core/m_types'; + +import { HIDDEN_COLUMNS_WIDTH } from '../const'; + +export const adaptivityDraggingHeaderExtender = ( + Base: ModuleType, +): ModuleType => class AdaptivityDraggingHeaderExtender extends Base { + protected _pointCreated({ + point, columns, location, sourceColumn, cells, + }) { + const result = super._pointCreated({ + point, columns, location, sourceColumn, cells, + }); + const column = columns[point.columnIndex - 1] || {}; + const hasAdaptiveHiddenWidth = column.visibleWidth === HIDDEN_COLUMNS_WIDTH; + + return result || hasAdaptiveHiddenWidth; + } +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_editing.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_editing.ts new file mode 100644 index 000000000000..fe7f4209dff7 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_editing.ts @@ -0,0 +1,151 @@ +/* eslint-disable @stylistic/max-len */ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable prefer-rest-params */ +import { Deferred, when } from '@js/core/utils/deferred'; +import type { EditingController } from '@ts/grids/grid_core/editing/m_editing'; +import type { ModuleType } from '@ts/grids/grid_core/m_types'; +import gridCoreUtils from '@ts/grids/grid_core/m_utils'; + +import { + ADAPTIVE_ROW_TYPE, + EDIT_MODE_BATCH, + EDIT_MODE_ROW, + FORM_ITEM_CONTENT_CLASS, +} from '../const'; + +export const adaptivityEditingExtender = ( + Base: ModuleType, +): ModuleType => class AdaptivityEditingExtender extends Base { + private _isForceRowAdaptiveExpand?: boolean; + + private _isRowEditMode() { + return this.getEditMode() === EDIT_MODE_ROW; + } + + protected _getFormEditItemTemplate(cellOptions, column) { + if (this.getEditMode() !== EDIT_MODE_ROW && cellOptions.rowType === 'detailAdaptive') { + cellOptions.columnIndex = this._columnsController.getVisibleIndex(column.index); + return this.getColumnTemplate(cellOptions); + } + + return super._getFormEditItemTemplate(cellOptions, column); + } + + protected _closeEditItem($targetElement) { + const $itemContents = $targetElement.closest(`.${FORM_ITEM_CONTENT_CLASS}`); + // @ts-expect-error + const rowIndex = this._dataController.getRowIndexByKey(this._dataController.getAdaptiveExpandedKey()) + 1; + const formItem = $itemContents.length ? $itemContents.first().data('dx-form-item') : null; + const columnIndex = formItem?.column && this._columnsController.getVisibleIndex(formItem.column.index); + + if (!this.isEditCell(rowIndex, columnIndex)) { + super._closeEditItem($targetElement); + } + } + + protected _beforeUpdateItems(rowIndices, rowIndex) { + if (!this.adaptiveColumnsController.isFormOrPopupEditMode() && this.adaptiveColumnsController.hasHiddenColumns()) { + const items = this._dataController.items(); + const item = items[rowIndex]; + // @ts-expect-error + const oldExpandRowIndex = gridCoreUtils.getIndexByKey(this._dataController.getAdaptiveExpandedKey(), items); + + this._isForceRowAdaptiveExpand = !this.adaptiveColumnsController.hasAdaptiveDetailRowExpanded(); + + if (oldExpandRowIndex >= 0) { + rowIndices.push(oldExpandRowIndex + 1); + } + + rowIndices.push(rowIndex + 1); + // @ts-expect-error + this._dataController.setAdaptiveExpandedKey(item.key); + } + } + + protected _afterInsertRow(key) { + super._afterInsertRow.apply(this, arguments as any); + + if (this.adaptiveColumnsController.hasHiddenColumns()) { + // @ts-expect-error + this.adaptiveColumnsController.toggleExpandAdaptiveDetailRow(key, this.isRowEditMode()); + this._isForceRowAdaptiveExpand = true; + } + } + + private _collapseAdaptiveDetailRow() { + if (this._isRowEditMode() && this._isForceRowAdaptiveExpand) { + this.adaptiveColumnsController.collapseAdaptiveDetailRow(); + this._isForceRowAdaptiveExpand = false; + } + } + + private _cancelEditAdaptiveDetailRow() { + if (this.adaptiveColumnsController.hasHiddenColumns()) { + this._collapseAdaptiveDetailRow(); + } + } + + protected _afterSaveEditData() { + super._afterSaveEditData.apply(this, arguments as any); + // @ts-expect-error + const deferred = new Deferred(); + if (this._isRowEditMode() && this.adaptiveColumnsController.hasHiddenColumns()) { + when(this._validatingController.validate(true)).done((isValid) => { + if (isValid) { + this._cancelEditAdaptiveDetailRow(); + } + deferred.resolve(); + }); + } else { + deferred.resolve(); + } + return deferred.promise(); + } + + protected _beforeCancelEditData() { + super._beforeCancelEditData(); + this._cancelEditAdaptiveDetailRow(); + } + + protected _getRowIndicesForCascadeUpdating(row) { + const rowIndices = super._getRowIndicesForCascadeUpdating.apply(this, arguments as any); + + if (this.adaptiveColumnsController.isAdaptiveDetailRowExpanded(row.key)) { + rowIndices.push(row.rowType === ADAPTIVE_ROW_TYPE ? row.rowIndex - 1 : row.rowIndex + 1); + } + + return rowIndices; + } + + protected _beforeCloseEditCellInBatchMode(rowIndices) { + // @ts-expect-error + const expandedKey = this._dataController.adaptiveExpandedKey; + + if (expandedKey) { + const rowIndex = gridCoreUtils.getIndexByKey(expandedKey, this._dataController.items()); + if (rowIndex > -1) { + rowIndices.unshift(rowIndex); + } + } + } + + public editRow(rowIndex) { + if (this.adaptiveColumnsController.isFormOrPopupEditMode()) { + this.adaptiveColumnsController.collapseAdaptiveDetailRow(); + } + + return super.editRow(rowIndex); + } + + protected deleteRow(rowIndex) { + const rowKey = this._dataController.getKeyByRowIndex(rowIndex); + + if (this.getEditMode() === EDIT_MODE_BATCH && this.adaptiveColumnsController.isAdaptiveDetailRowExpanded(rowKey)) { + this.adaptiveColumnsController.collapseAdaptiveDetailRow(); + } + + super.deleteRow(rowIndex); + } +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_editor_factory.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_editor_factory.ts new file mode 100644 index 000000000000..1377b7b51db9 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_editor_factory.ts @@ -0,0 +1,25 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +import type { EditorFactory } from '@ts/grids/grid_core/editor_factory/m_editor_factory'; +import type { ModuleType } from '@ts/grids/grid_core/m_types'; + +import { REVERT_TOOLTIP_CLASS } from '../const'; + +export const adaptivityEditorFactoryExtender = ( + Base: ModuleType, +): ModuleType => class AdaptivityEditorFactoryExtender extends Base { + protected _needHideBorder($element) { + return super._needHideBorder($element) || ($element?.hasClass('dx-field-item-content') && $element?.find('.dx-checkbox').length); + } + + protected _getFocusCellSelector() { + return `${super._getFocusCellSelector()}, .dx-adaptive-detail-row .dx-field-item > .dx-field-item-content`; + } + + /** + * Overrides interface + */ + public _getRevertTooltipsSelector() { + return `${super._getRevertTooltipsSelector()}, .dx-field-item-content .${this.addWidgetPrefix(REVERT_TOOLTIP_CLASS)}`; + } +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_export.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_export.ts new file mode 100644 index 000000000000..f43450e8e5f0 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_export.ts @@ -0,0 +1,15 @@ +import type { ExportController } from '@ts/grids/data_grid/export/m_export'; +import type { ModuleType } from '@ts/grids/grid_core/m_types'; + +import { HIDDEN_COLUMNS_WIDTH } from '../const'; + +export const adaptivityExportExtender = ( + Base: ModuleType, +): ModuleType => class AdaptivityExportExtender extends Base { + protected _updateColumnWidth(column, width): void { + super._updateColumnWidth( + column, + column.visibleWidth === HIDDEN_COLUMNS_WIDTH ? column.bestFitWidth : width, + ); + } +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_headers_keyboard_navigation.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_headers_keyboard_navigation.ts new file mode 100644 index 000000000000..b0155a1d29f8 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_headers_keyboard_navigation.ts @@ -0,0 +1,45 @@ +/* eslint-disable @stylistic/max-len */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import type { Column } from '@ts/grids/grid_core/columns_controller/types'; +import type { Direction } from '@ts/grids/grid_core/keyboard_navigation/const'; +import type { HeadersKeyboardNavigationController } from '@ts/grids/grid_core/keyboard_navigation/m_headers_keyboard_navigation'; +import type { ModuleType } from '@ts/grids/grid_core/m_types'; + +import { HIDDEN_COLUMNS_WIDTH } from '../const'; + +export const adaptivityHeadersKeyboardNavigationExtender = ( + Base: ModuleType, +): ModuleType => class AdaptivityHeadersKeyboardNavigationExtender + extends Base { + protected getColumnVisibleIndexCorrection( + visibleIndex: number, + rowIndex: number, + direction: Direction, + ): number { + let indexCorrection = super.getColumnVisibleIndexCorrection(visibleIndex, rowIndex, direction); + let visibleColumns = this._columnsController.getVisibleColumns(rowIndex); + + visibleColumns = direction === 'next' + ? visibleColumns.slice(visibleIndex + 1) + : visibleColumns.slice(0, visibleIndex).reverse(); + + while (visibleColumns?.shift()?.visibleWidth === HIDDEN_COLUMNS_WIDTH) { + indexCorrection += direction === 'next' ? 1 : -1; + } + + return indexCorrection; + } + + protected getFocusableColumns(rowIndex?: number, bandColumnId?: number): Column[] { + return super.getFocusableColumns(rowIndex, bandColumnId) + .filter((col) => col.visibleWidth !== HIDDEN_COLUMNS_WIDTH); + } + + protected getDraggableColumns( + column, + rowIndex: number, + ): any[] { + return super.getDraggableColumns(column, rowIndex) + .filter((col) => col.visibleWidth !== HIDDEN_COLUMNS_WIDTH); + } +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_keyboard_navigation.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_keyboard_navigation.ts new file mode 100644 index 000000000000..da46541bb976 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_keyboard_navigation.ts @@ -0,0 +1,62 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +import eventsEngine from '@js/common/core/events/core/events_engine'; +import type { Column } from '@ts/grids/grid_core/columns_controller/types'; +import type { KeyboardNavigationController } from '@ts/grids/grid_core/keyboard_navigation/m_keyboard_navigation'; +import type { ModuleType } from '@ts/grids/grid_core/m_types'; + +import { + ADAPTIVE_ITEM_TEXT_CLASS, + COMMAND_ADAPTIVE_HIDDEN_CLASS, + HIDDEN_COLUMN_CLASS, + HIDDEN_COLUMNS_WIDTH, +} from '../const'; + +function focusCellHandler(e): void { + const $nextCell = e.data?.$nextCell; + + eventsEngine.off($nextCell, 'focus', focusCellHandler); + // @ts-expect-error + eventsEngine.trigger($nextCell, 'dxclick'); +} + +export const adaptivityKeyboardNavigationExtender = ( + Base: ModuleType, +): ModuleType => class AdaptivityKeyboardNavigationExtender + extends Base { + public _isCellValid($cell, isClick?) { + return ( + super._isCellValid($cell, isClick) + && !$cell.hasClass(this.addWidgetPrefix(HIDDEN_COLUMN_CLASS)) + && !$cell.hasClass(COMMAND_ADAPTIVE_HIDDEN_CLASS) + ); + } + + protected _processNextCellInMasterDetail($nextCell, $cell) { + super._processNextCellInMasterDetail($nextCell, $cell); + + const isCellOrBatchMode = this._editingController.isCellOrBatchEditMode(); + const isEditing = this._editingController.isEditing(); + + if ( + isEditing + && $nextCell + && isCellOrBatchMode + && !this._isInsideEditForm($nextCell) + ) { + eventsEngine.off($nextCell, 'focus', focusCellHandler); + eventsEngine.on($nextCell, 'focus', { $nextCell }, focusCellHandler); + + // @ts-expect-error + eventsEngine.trigger($cell, 'focus'); + } + } + + protected isFocusableColumn(column: Column): boolean { + return super.isFocusableColumn(column) && column.visibleWidth !== HIDDEN_COLUMNS_WIDTH; + } + + public _isCellElement($cell) { + return super._isCellElement($cell) || $cell.hasClass(ADAPTIVE_ITEM_TEXT_CLASS); + } +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_resizing_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_resizing_controller.ts new file mode 100644 index 000000000000..d8fc34b04aa1 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_resizing_controller.ts @@ -0,0 +1,83 @@ +/* eslint-disable @stylistic/max-len */ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-unused-expressions */ +/* eslint-disable prefer-rest-params */ +import type { Column } from '@ts/grids/grid_core/columns_controller/types'; +import type { ModuleType } from '@ts/grids/grid_core/m_types'; +import type { ResizingController } from '@ts/grids/grid_core/views/m_grid_view'; + +import { COLUMN_VIEWS } from '../const'; + +export const adaptivityResizingControllerExtender = ( + Base: ModuleType, +): ModuleType => class AdaptivityResizingControllerExtender extends Base { + public dispose() { + super.dispose.apply(this, arguments as any); + clearTimeout(this._updateScrollableTimeoutID); + } + + private isHiddenColumnsChanged( + oldHiddenColumns: Column[], + hiddenColumns: Column[], + ): boolean { + if (oldHiddenColumns.length !== hiddenColumns.length) { + return true; + } + + const oldIndices = new Set(oldHiddenColumns.map((col) => col.index)); + + return hiddenColumns.some((col) => !oldIndices.has(col.index)); + } + + private updateColumnViewsFirstCellClasses(): void { + COLUMN_VIEWS.forEach((viewName) => { + const view = this.getView(viewName); + + if (view?.isVisible()) { + view.updateFirstCellClasses(); + } + }); + } + + protected _needBestFit() { + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + return super._needBestFit() || !!this.adaptiveColumnsController.getHidingColumnsQueue().length; + } + + protected _correctColumnWidths(resultWidths: (number | string | undefined)[], visibleColumns: Column[]): boolean { + const adaptiveController = this.adaptiveColumnsController; + const oldHiddenColumns = adaptiveController.getHiddenColumns(); + const hidingColumnsQueue = adaptiveController.updateHidingQueue(this._columnsController.getColumns()); + + adaptiveController.hideRedundantColumns(resultWidths, visibleColumns, hidingColumnsQueue); + const hiddenColumns = adaptiveController.getHiddenColumns(); + const isHiddenColumnsChanged = this.isHiddenColumnsChanged(oldHiddenColumns, hiddenColumns); + + if (isHiddenColumnsChanged && adaptiveController.hasAdaptiveDetailRowExpanded()) { + adaptiveController.updateForm(hiddenColumns); + } + + if (isHiddenColumnsChanged) { + this.updateColumnViewsFirstCellClasses(); + } + + if (!hiddenColumns.length) { + adaptiveController.collapseAdaptiveDetailRow(); + } + + return super._correctColumnWidths.apply(this, arguments as any); + } + + protected _toggleBestFitMode(isBestFit) { + this.adaptiveColumnsController._toggleGroupAdaptiveRowVisibility(isBestFit); + isBestFit && this.adaptiveColumnsController._showHiddenColumns(); + super._toggleBestFitMode(isBestFit); + } + + protected _needStretch() { + const { adaptiveColumnsController } = this; + return super._needStretch.apply(this, arguments as any) || adaptiveColumnsController.getHidingColumnsQueue().length || adaptiveColumnsController.hasHiddenColumns(); + } +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_rows_view.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_rows_view.ts new file mode 100644 index 000000000000..57de14d79832 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_rows_view.ts @@ -0,0 +1,125 @@ +/* eslint-disable @stylistic/max-len */ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-shadow */ +/* eslint-disable @typescript-eslint/no-this-alias */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable prefer-rest-params */ +import type { dxElementWrapper } from '@js/core/renderer'; +import $ from '@js/core/renderer'; +import type { ModuleType } from '@ts/grids/grid_core/m_types'; +import type { RowsView } from '@ts/grids/grid_core/views/m_rows_view'; + +import { + ADAPTIVE_COLUMN_NAME_CLASS, + ADAPTIVE_DETAIL_ROW_CLASS, + ADAPTIVE_ROW_TYPE, + EXPAND_ARIA_NAME, + FORM_ITEM_CONTENT_CLASS, + HIDDEN_COLUMN_CLASS, + HIDDEN_COLUMNS_WIDTH, + LAST_DATA_CELL_CLASS, +} from '../const'; + +function getDataCellElements($row) { + return $row.find('td:not(.dx-datagrid-hidden-column):not([class*=\'dx-command-\'])'); +} + +export const adaptivityRowsViewExtender = ( + Base: ModuleType, +): ModuleType => class AdaptivityRowsViewExtender extends Base { + protected _getCellTemplate(options) { + const that = this; + const { column } = options; + + if (options.rowType === ADAPTIVE_ROW_TYPE && column.command === 'detail') { + return function (container, options) { + that.adaptiveColumnsController.createFormByHiddenColumns($(container), options); + }; + } + return super._getCellTemplate(options); + } + + protected _createRow(row) { + const $row = super._createRow.apply(this, arguments as any); + + // @ts-expect-error + if (row?.rowType === ADAPTIVE_ROW_TYPE && row.key === this._dataController.getAdaptiveExpandedKey()) { + $row.addClass(ADAPTIVE_DETAIL_ROW_CLASS); + } + return $row; + } + + protected _renderCells($row, options) { + super._renderCells($row, options); + + const { adaptiveColumnsController } = this; + const hidingColumnsQueueLength = adaptiveColumnsController.getHidingColumnsQueue().length; + const hiddenColumnsLength = adaptiveColumnsController.getHiddenColumns().length; + + if (hidingColumnsQueueLength && !hiddenColumnsLength) { + getDataCellElements($row).last().addClass(LAST_DATA_CELL_CLASS); + } + + if (options.row.rowType === 'data') { + adaptiveColumnsController.setCommandAdaptiveAriaLabel($row, EXPAND_ARIA_NAME); + } + } + + private _getColumnIndexByElementCore($element) { + const $itemContent = $element.closest(`.${FORM_ITEM_CONTENT_CLASS}`); + if ($itemContent.length && $itemContent.closest(this.component.$element()).length) { + const formItem = $itemContent.length ? $itemContent.first().data('dx-form-item') : null; + return formItem?.column && this._columnsController.getVisibleIndex(formItem.column.index); + } + // @ts-expect-error + return super._getColumnIndexByElementCore($element); + } + + public _cellPrepared($cell, options) { + super._cellPrepared.apply(this, arguments as any); + + if (options.row.rowType !== ADAPTIVE_ROW_TYPE && options.column.visibleWidth === HIDDEN_COLUMNS_WIDTH) { + $cell.addClass(this.addWidgetPrefix(HIDDEN_COLUMN_CLASS)); + } + } + + public getCell(cellPosition, rows) { + const item = this._dataController.items()[cellPosition?.rowIndex]; + + if (item?.rowType === ADAPTIVE_ROW_TYPE) { + const $adaptiveDetailItems = this.adaptiveColumnsController.getAdaptiveDetailItems(); + + return super.getCell(cellPosition, rows, $adaptiveDetailItems); + } + return super.getCell.apply(this, arguments as any); + } + + public _getCellElement(rowIndex, columnIdentifier): dxElementWrapper | undefined { + const item = this._dataController.items()[rowIndex]; + + if (item?.rowType === ADAPTIVE_ROW_TYPE) { + return this.adaptiveColumnsController.getItemContentByColumnIndex(columnIdentifier); + } + return super._getCellElement.apply(this, arguments as any); + } + + private getContextMenuItems(options) { + if (options.row?.rowType === 'detailAdaptive') { + const view = this._columnHeadersView; + const formItem = $(options.targetElement).closest('.dx-field-item-label').next().data('dx-form-item'); + // @ts-expect-error + options.column = formItem ? formItem.column : options.column; + return view.getContextMenuItems?.(options); + } + // @ts-expect-error + return super.getContextMenuItems?.(options); + } + + private isClickableElement($target) { + // @ts-expect-error + const isClickable = super.isClickableElement?.($target) ?? false; + + return isClickable || !!$target.closest(`.${ADAPTIVE_COLUMN_NAME_CLASS}`).length; + } +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts index d689f5a1c221..0ce3c0b15f77 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts @@ -1,14 +1,11 @@ -/* eslint-disable max-classes-per-file */ import { name as clickEventName } from '@js/common/core/events/click'; import eventsEngine from '@js/common/core/events/core/events_engine'; import { removeEvent } from '@js/common/core/events/remove'; import { addNamespace } from '@js/common/core/events/utils/index'; import messageLocalization from '@js/common/core/localization/message'; import Guid from '@js/core/guid'; -import type { dxElementWrapper } from '@js/core/renderer'; import $ from '@js/core/renderer'; import { equalByValue } from '@js/core/utils/common'; -import { Deferred, when } from '@js/core/utils/deferred'; import { isElementInDom } from '@js/core/utils/dom'; import { extend } from '@js/core/utils/extend'; import { each } from '@js/core/utils/iterator'; @@ -17,67 +14,43 @@ import { isDefined, isString } from '@js/core/utils/type'; import Form from '@js/ui/form'; import { isMaterial } from '@js/ui/themes'; import type { Column } from '@ts/grids/grid_core/columns_controller/types'; -import type { ResizingController } from '@ts/grids/grid_core/views/m_grid_view'; -import type { ExportController } from '../../data_grid/export/m_export'; import { AI_COLUMN_NAME } from '../ai_column/const'; import type { ColumnsController } from '../columns_controller/m_columns_controller'; -import type { ColumnsResizerViewController, DraggingHeaderViewController } from '../columns_resizing_reordering/m_columns_resizing_reordering'; import type { DataController } from '../data_controller/data_controller'; -import type { DataChange, ProcessedItem } from '../data_controller/types'; -import type { RawItemData } from '../data_source_adapter/types'; import type { EditingController } from '../editing/m_editing'; -import type { EditorFactory } from '../editor_factory/m_editor_factory'; -import type { Direction } from '../keyboard_navigation/const'; -import type { HeadersKeyboardNavigationController } from '../keyboard_navigation/m_headers_keyboard_navigation'; import type { KeyboardNavigationController } from '../keyboard_navigation/m_keyboard_navigation'; import modules from '../m_modules'; -import type { Module, ModuleType } from '../m_types'; import gridCoreUtils from '../m_utils'; import type { RowsView } from '../views/m_rows_view'; +import { + ADAPTIVE_COLUMN_BUTTON_CLASS, + ADAPTIVE_COLUMN_NAME, + ADAPTIVE_COLUMN_NAME_CLASS, + ADAPTIVE_ITEM_TEXT_CLASS, + ADAPTIVE_NAMESPACE, + ADAPTIVE_ROW_TYPE, + COLUMN_HEADERS_VIEW, + COLUMN_VIEWS, + COMMAND_ADAPTIVE_HIDDEN_CLASS, + EDIT_MODE_FORM, + EDIT_MODE_POPUP, + EDIT_MODE_ROW, + FORM_ITEM_CONTENT_CLASS, + FORM_ITEM_MODIFIED, + GROUP_CELL_CLASS, + GROUP_ROW_CLASS, + HIDDEN_COLUMN_CLASS, + HIDDEN_COLUMNS_WIDTH, + MASTER_DETAIL_CELL_CLASS, + ROWS_VIEW, +} from './const'; import { getHideableColumns } from './utils'; -const COLUMN_HEADERS_VIEW = 'columnHeadersView' as const; -const ROWS_VIEW = 'rowsView' as const; -const FOOTER_VIEW = 'footerView' as const; -const COLUMN_VIEWS = [COLUMN_HEADERS_VIEW, ROWS_VIEW, FOOTER_VIEW] as const; - -const ADAPTIVE_NAMESPACE = 'dxDataGridAdaptivity'; -const HIDDEN_COLUMNS_WIDTH = 'adaptiveHidden'; -const ADAPTIVE_ROW_TYPE = 'detailAdaptive'; - -const FORM_ITEM_CONTENT_CLASS = 'dx-field-item-content'; -const FORM_ITEM_MODIFIED = 'dx-item-modified'; - -const HIDDEN_COLUMN_CLASS = 'hidden-column'; -const ADAPTIVE_COLUMN_BUTTON_CLASS = 'adaptive-more'; -const ADAPTIVE_COLUMN_NAME_CLASS = 'dx-command-adaptive'; -const COMMAND_ADAPTIVE_HIDDEN_CLASS = 'dx-command-adaptive-hidden'; -const ADAPTIVE_DETAIL_ROW_CLASS = 'dx-adaptive-detail-row'; -const ADAPTIVE_ITEM_TEXT_CLASS = 'dx-adaptive-item-text'; -const MASTER_DETAIL_CELL_CLASS = 'dx-master-detail-cell'; -const LAST_DATA_CELL_CLASS = 'dx-last-data-cell'; -const ADAPTIVE_COLUMN_NAME = 'adaptive'; -const EDIT_MODE_BATCH = 'batch'; -const EDIT_MODE_ROW = 'row'; -const EDIT_MODE_FORM = 'form'; -const EDIT_MODE_POPUP = 'popup'; -const REVERT_TOOLTIP_CLASS = 'revert-tooltip'; -const GROUP_CELL_CLASS = 'dx-group-cell'; -const GROUP_ROW_CLASS = 'dx-group-row'; - -const EXPAND_ARIA_NAME = 'dxDataGrid-ariaAdaptiveExpand'; -const COLLAPSE_ARIA_NAME = 'dxDataGrid-ariaAdaptiveCollapse'; -const LEGACY_SCROLLING_MODE = 'scrolling.legacyMode'; - function getColumnId(that, column) { return that._columnsController.getColumnId(column); } -function getDataCellElements($row) { - return $row.find('td:not(.dx-datagrid-hidden-column):not([class*=\'dx-command-\'])'); -} - function adaptiveCellTemplate(container, options) { let $adaptiveColumnButton; const $container = $(container); @@ -95,14 +68,6 @@ function adaptiveCellTemplate(container, options) { } } -function focusCellHandler(e) { - const $nextCell = e.data?.$nextCell; - - eventsEngine.off($nextCell, 'focus', focusCellHandler); - // @ts-expect-error - eventsEngine.trigger($nextCell, 'dxclick'); -} - export class AdaptiveColumnsController extends modules.ViewController { private _columnsController!: ColumnsController; @@ -430,12 +395,12 @@ export class AdaptiveColumnsController extends modules.ViewController { if (this._isRowEditMode()) { const editRowKey = this.option('editing.editRowKey'); // @ts-expect-error - if (equalByValue(editRowKey, this._dataController.adaptiveExpandedKey())) { + if (equalByValue(editRowKey, this._dataController.getAdaptiveExpandedKey())) { return true; } } else { // @ts-expect-error - const rowIndex = this._dataController.getRowIndexByKey(this._dataController.adaptiveExpandedKey()) + 1; + const rowIndex = this._dataController.getRowIndexByKey(this._dataController.getAdaptiveExpandedKey()) + 1; const columnIndex = this._columnsController.getVisibleIndex(item.column.index); return this._editingController.isEditCell(rowIndex, columnIndex); @@ -753,7 +718,7 @@ export class AdaptiveColumnsController extends modules.ViewController { public hasAdaptiveDetailRowExpanded() { // @ts-expect-error - return isDefined(this._dataController.adaptiveExpandedKey()); + return isDefined(this._dataController.getAdaptiveExpandedKey()); } public updateForm(hiddenColumns) { @@ -817,7 +782,7 @@ export class AdaptiveColumnsController extends modules.ViewController { public isAdaptiveDetailRowExpanded(key) { const dataController = this._dataController; // @ts-expect-error - return dataController.adaptiveExpandedKey() && equalByValue(dataController.adaptiveExpandedKey(), key); + return dataController.getAdaptiveExpandedKey() && equalByValue(dataController.getAdaptiveExpandedKey(), key); } private expandAdaptiveDetailRow(key) { @@ -857,604 +822,3 @@ export class AdaptiveColumnsController extends modules.ViewController { .filter((hiddenColumn) => hiddenColumn.index === column.index).length > 0; } } - -const keyboardNavigation = ( - Base: ModuleType, -) => class AdaptivityKeyboardNavigationExtender extends Base { - public _isCellValid($cell, isClick?) { - return ( - super._isCellValid($cell, isClick) - && !$cell.hasClass(this.addWidgetPrefix(HIDDEN_COLUMN_CLASS)) - && !$cell.hasClass(COMMAND_ADAPTIVE_HIDDEN_CLASS) - ); - } - - protected _processNextCellInMasterDetail($nextCell, $cell) { - super._processNextCellInMasterDetail($nextCell, $cell); - - const isCellOrBatchMode = this._editingController.isCellOrBatchEditMode(); - const isEditing = this._editingController.isEditing(); - - if ( - isEditing - && $nextCell - && isCellOrBatchMode - && !this._isInsideEditForm($nextCell) - ) { - eventsEngine.off($nextCell, 'focus', focusCellHandler); - eventsEngine.on($nextCell, 'focus', { $nextCell }, focusCellHandler); - - // @ts-expect-error - eventsEngine.trigger($cell, 'focus'); - } - } - - protected isFocusableColumn(column: Column): boolean { - return super.isFocusableColumn(column) && column.visibleWidth !== HIDDEN_COLUMNS_WIDTH; - } - - public _isCellElement($cell) { - return super._isCellElement($cell) || $cell.hasClass(ADAPTIVE_ITEM_TEXT_CLASS); - } -}; - -const rowsView = ( - Base: ModuleType, -) => class AdaptivityRowsViewExtender extends Base { - protected _getCellTemplate(options) { - const that = this; - const { column } = options; - - if (options.rowType === ADAPTIVE_ROW_TYPE && column.command === 'detail') { - return function (container, options) { - that.adaptiveColumnsController.createFormByHiddenColumns($(container), options); - }; - } - return super._getCellTemplate(options); - } - - protected _createRow(row) { - const $row = super._createRow.apply(this, arguments as any); - - // @ts-expect-error - if (row && row.rowType === ADAPTIVE_ROW_TYPE && row.key === this._dataController.adaptiveExpandedKey()) { - $row.addClass(ADAPTIVE_DETAIL_ROW_CLASS); - } - return $row; - } - - protected _renderCells($row, options) { - super._renderCells($row, options); - - const { adaptiveColumnsController } = this; - const hidingColumnsQueueLength = adaptiveColumnsController.getHidingColumnsQueue().length; - const hiddenColumnsLength = adaptiveColumnsController.getHiddenColumns().length; - - if (hidingColumnsQueueLength && !hiddenColumnsLength) { - getDataCellElements($row).last().addClass(LAST_DATA_CELL_CLASS); - } - - if (options.row.rowType === 'data') { - adaptiveColumnsController.setCommandAdaptiveAriaLabel($row, EXPAND_ARIA_NAME); - } - } - - private _getColumnIndexByElementCore($element) { - const $itemContent = $element.closest(`.${FORM_ITEM_CONTENT_CLASS}`); - if ($itemContent.length && $itemContent.closest(this.component.$element()).length) { - const formItem = $itemContent.length ? $itemContent.first().data('dx-form-item') : null; - return formItem && formItem.column && this._columnsController.getVisibleIndex(formItem.column.index); - } - // @ts-expect-error - return super._getColumnIndexByElementCore($element); - } - - public _cellPrepared($cell, options) { - super._cellPrepared.apply(this, arguments as any); - - if (options.row.rowType !== ADAPTIVE_ROW_TYPE && options.column.visibleWidth === HIDDEN_COLUMNS_WIDTH) { - $cell.addClass(this.addWidgetPrefix(HIDDEN_COLUMN_CLASS)); - } - } - - public getCell(cellPosition, rows) { - const item = this._dataController.items()[cellPosition?.rowIndex]; - - if (item?.rowType === ADAPTIVE_ROW_TYPE) { - const $adaptiveDetailItems = this.adaptiveColumnsController.getAdaptiveDetailItems(); - - return super.getCell(cellPosition, rows, $adaptiveDetailItems); - } - return super.getCell.apply(this, arguments as any); - } - - public _getCellElement(rowIndex, columnIdentifier): dxElementWrapper | undefined { - const item = this._dataController.items()[rowIndex]; - - if (item && item.rowType === ADAPTIVE_ROW_TYPE) { - return this.adaptiveColumnsController.getItemContentByColumnIndex(columnIdentifier); - } - return super._getCellElement.apply(this, arguments as any); - } - - private getContextMenuItems(options) { - if (options.row && options.row.rowType === 'detailAdaptive') { - const view = this._columnHeadersView; - const formItem = $(options.targetElement).closest('.dx-field-item-label').next().data('dx-form-item'); - // @ts-expect-error - options.column = formItem ? formItem.column : options.column; - return view.getContextMenuItems && view.getContextMenuItems(options); - } - // @ts-expect-error - return super.getContextMenuItems?.(options); - } - - private isClickableElement($target) { - // @ts-expect-error - const isClickable = super.isClickableElement?.($target) ?? false; - - return isClickable || !!$target.closest(`.${ADAPTIVE_COLUMN_NAME_CLASS}`).length; - } -}; - -const exportExtender = ( - Base: ModuleType, -) => class AdaptivityExportExtender extends Base { - protected _updateColumnWidth(column, width): void { - super._updateColumnWidth( - column, - column.visibleWidth === HIDDEN_COLUMNS_WIDTH ? column.bestFitWidth : width, - ); - } -}; - -const columnsResizer = ( - Base: ModuleType, -) => class AdaptivityColumnsResizerExtender extends Base { - protected _pointCreated(point, columns, cells?: dxElementWrapper) { - const result = super._pointCreated(point, columns, cells); - const currentColumn = columns[point.columnIndex] || {}; - const nextColumnIndex = this._getNextColumnIndex(point.columnIndex); - const nextColumn = columns[nextColumnIndex] || {}; - const hasHiddenColumnsOnly = nextColumnIndex !== point.columnIndex + 1 && nextColumn.command; - const hasAdaptiveHiddenWidth = currentColumn.visibleWidth === HIDDEN_COLUMNS_WIDTH || hasHiddenColumnsOnly; - - return result || hasAdaptiveHiddenWidth; - } - - protected _getNextColumnIndex(currentColumnIndex) { - const visibleColumns = this._columnsController.getVisibleColumns(); - let index = super._getNextColumnIndex(currentColumnIndex); - - while (visibleColumns[index] && visibleColumns[index].visibleWidth === HIDDEN_COLUMNS_WIDTH) { - index++; - } - - return index; - } -}; - -const draggingHeader = ( - Base: ModuleType, -) => class AdaptivityDraggingHeaderExtender extends Base { - protected _pointCreated({ - point, columns, location, sourceColumn, cells, - }) { - const result = super._pointCreated({ - point, columns, location, sourceColumn, cells, - }); - const column = columns[point.columnIndex - 1] || {}; - const hasAdaptiveHiddenWidth = column.visibleWidth === HIDDEN_COLUMNS_WIDTH; - - return result || hasAdaptiveHiddenWidth; - } -}; - -const editing = ( - Base: ModuleType, -) => class AdaptivityEditingExtender extends Base { - private _isForceRowAdaptiveExpand?: boolean; - - private _isRowEditMode() { - return this.getEditMode() === EDIT_MODE_ROW; - } - - protected _getFormEditItemTemplate(cellOptions, column) { - if (this.getEditMode() !== EDIT_MODE_ROW && cellOptions.rowType === 'detailAdaptive') { - cellOptions.columnIndex = this._columnsController.getVisibleIndex(column.index); - return this.getColumnTemplate(cellOptions); - } - - return super._getFormEditItemTemplate(cellOptions, column); - } - - protected _closeEditItem($targetElement) { - const $itemContents = $targetElement.closest(`.${FORM_ITEM_CONTENT_CLASS}`); - // @ts-expect-error - const rowIndex = this._dataController.getRowIndexByKey(this._dataController.adaptiveExpandedKey()) + 1; - const formItem = $itemContents.length ? $itemContents.first().data('dx-form-item') : null; - const columnIndex = formItem && formItem.column && this._columnsController.getVisibleIndex(formItem.column.index); - - if (!this.isEditCell(rowIndex, columnIndex)) { - super._closeEditItem($targetElement); - } - } - - protected _beforeUpdateItems(rowIndices, rowIndex) { - if (!this.adaptiveColumnsController.isFormOrPopupEditMode() && this.adaptiveColumnsController.hasHiddenColumns()) { - const items = this._dataController.items(); - const item = items[rowIndex]; - // @ts-expect-error - const oldExpandRowIndex = gridCoreUtils.getIndexByKey(this._dataController.adaptiveExpandedKey(), items); - - this._isForceRowAdaptiveExpand = !this.adaptiveColumnsController.hasAdaptiveDetailRowExpanded(); - - if (oldExpandRowIndex >= 0) { - rowIndices.push(oldExpandRowIndex + 1); - } - - rowIndices.push(rowIndex + 1); - // @ts-expect-error - this._dataController.adaptiveExpandedKey(item.key); - } - } - - protected _afterInsertRow(key) { - super._afterInsertRow.apply(this, arguments as any); - - if (this.adaptiveColumnsController.hasHiddenColumns()) { - // @ts-expect-error - this.adaptiveColumnsController.toggleExpandAdaptiveDetailRow(key, this.isRowEditMode()); - this._isForceRowAdaptiveExpand = true; - } - } - - private _collapseAdaptiveDetailRow() { - if (this._isRowEditMode() && this._isForceRowAdaptiveExpand) { - this.adaptiveColumnsController.collapseAdaptiveDetailRow(); - this._isForceRowAdaptiveExpand = false; - } - } - - private _cancelEditAdaptiveDetailRow() { - if (this.adaptiveColumnsController.hasHiddenColumns()) { - this._collapseAdaptiveDetailRow(); - } - } - - protected _afterSaveEditData() { - super._afterSaveEditData.apply(this, arguments as any); - // @ts-expect-error - const deferred = new Deferred(); - if (this._isRowEditMode() && this.adaptiveColumnsController.hasHiddenColumns()) { - when(this._validatingController.validate(true)).done((isValid) => { - if (isValid) { - this._cancelEditAdaptiveDetailRow(); - } - deferred.resolve(); - }); - } else { - deferred.resolve(); - } - return deferred.promise(); - } - - protected _beforeCancelEditData() { - super._beforeCancelEditData(); - this._cancelEditAdaptiveDetailRow(); - } - - protected _getRowIndicesForCascadeUpdating(row) { - const rowIndices = super._getRowIndicesForCascadeUpdating.apply(this, arguments as any); - - if (this.adaptiveColumnsController.isAdaptiveDetailRowExpanded(row.key)) { - rowIndices.push(row.rowType === ADAPTIVE_ROW_TYPE ? row.rowIndex - 1 : row.rowIndex + 1); - } - - return rowIndices; - } - - protected _beforeCloseEditCellInBatchMode(rowIndices) { - // @ts-expect-error - const expandedKey = this._dataController._adaptiveExpandedKey; - - if (expandedKey) { - const rowIndex = gridCoreUtils.getIndexByKey(expandedKey, this._dataController.items()); - if (rowIndex > -1) { - rowIndices.unshift(rowIndex); - } - } - } - - public editRow(rowIndex) { - if (this.adaptiveColumnsController.isFormOrPopupEditMode()) { - this.adaptiveColumnsController.collapseAdaptiveDetailRow(); - } - - return super.editRow(rowIndex); - } - - protected deleteRow(rowIndex) { - const rowKey = this._dataController.getKeyByRowIndex(rowIndex); - - if (this.getEditMode() === EDIT_MODE_BATCH && this.adaptiveColumnsController.isAdaptiveDetailRowExpanded(rowKey)) { - this.adaptiveColumnsController.collapseAdaptiveDetailRow(); - } - - super.deleteRow(rowIndex); - } -}; - -const data = ( - Base: ModuleType, -) => class AdaptivityDataControllerExtender extends Base { - private _adaptiveExpandedKey: any; - - protected adaptiveColumnsController!: AdaptiveColumnsController; - - public init() { - super.init(); - this._adaptiveExpandedKey = undefined; - this.adaptiveColumnsController = this.getController('adaptiveColumns'); - } - - protected _processItems(items: RawItemData[], change: DataChange): ProcessedItem[] { - const processedItems = super._processItems(items, change); - const { changeType } = change; - - if ((changeType === 'loadingAll') || !isDefined(this._adaptiveExpandedKey)) { - return processedItems; - } - - const expandRowIndex = gridCoreUtils.getIndexByKey(this._adaptiveExpandedKey, processedItems); - const newMode = this.option(LEGACY_SCROLLING_MODE) === false; - - if (expandRowIndex >= 0) { - const item = processedItems[expandRowIndex]; - processedItems.splice(expandRowIndex + 1, 0, { - visible: true, - rowType: ADAPTIVE_ROW_TYPE, - key: item.key, - data: item.data, - // @ts-expect-error treelist specific field - node: item.node, - modifiedValues: item.modifiedValues, - isNewRow: item.isNewRow, - values: item.values, - }); - } else if (changeType === 'refresh' && !(newMode && change.repaintChangesOnly)) { - this._adaptiveExpandedKey = undefined; - } - - return processedItems; - } - - private _getRowIndicesForExpand(key) { - // @ts-expect-error - const rowIndices = super._getRowIndicesForExpand.apply(this, arguments); - - if (this.adaptiveColumnsController.isAdaptiveDetailRowExpanded(key)) { - const lastRowIndex = rowIndices[rowIndices.length - 1]; - rowIndices.push(lastRowIndex + 1); - } - - return rowIndices; - } - - private adaptiveExpandedKey(value) { - if (isDefined(value)) { - this._adaptiveExpandedKey = value; - } else { - return this._adaptiveExpandedKey; - } - } - - private toggleExpandAdaptiveDetailRow(key, alwaysExpanded) { - const that = this; - - let oldExpandLoadedRowIndex = gridCoreUtils.getIndexByKey(that._adaptiveExpandedKey, that._items); - let newExpandLoadedRowIndex = gridCoreUtils.getIndexByKey(key, that._items); - - if (oldExpandLoadedRowIndex >= 0 && oldExpandLoadedRowIndex === newExpandLoadedRowIndex && !alwaysExpanded) { - key = undefined; - newExpandLoadedRowIndex = -1; - } - - const oldKey = that._adaptiveExpandedKey; - that._adaptiveExpandedKey = key; - - if (oldExpandLoadedRowIndex >= 0) { - oldExpandLoadedRowIndex++; - } - if (newExpandLoadedRowIndex >= 0) { - newExpandLoadedRowIndex++; - } - - const rowIndexDelta = that.getRowIndexDelta(); - - that.updateItems({ - allowInvisibleRowIndices: true, - changeType: 'update', - rowIndices: [oldExpandLoadedRowIndex - rowIndexDelta, newExpandLoadedRowIndex - rowIndexDelta], - }); - - this.adaptiveColumnsController.updateCommandAdaptiveAriaLabel(key, COLLAPSE_ARIA_NAME); - this.adaptiveColumnsController.updateCommandAdaptiveAriaLabel(oldKey, EXPAND_ARIA_NAME); - } -}; - -const editorFactory = ( - Base: ModuleType, -) => class AdaptivityEditorFactoryExtender extends Base { - protected _needHideBorder($element) { - return super._needHideBorder($element) || ($element?.hasClass('dx-field-item-content') && $element?.find('.dx-checkbox').length); - } - - protected _getFocusCellSelector() { - return `${super._getFocusCellSelector()}, .dx-adaptive-detail-row .dx-field-item > .dx-field-item-content`; - } - - /** - * Overrides interface - */ - public _getRevertTooltipsSelector() { - return `${super._getRevertTooltipsSelector()}, .dx-field-item-content .${this.addWidgetPrefix(REVERT_TOOLTIP_CLASS)}`; - } -}; - -const columns = ( - Base: ModuleType, -) => class AdaptivityColumnsExtender extends Base { - private adaptiveColumnsController!: AdaptiveColumnsController; - - public init(isApplyingUserState?: boolean): void { - super.init(isApplyingUserState); - this.adaptiveColumnsController = this.getController('adaptiveColumns'); - } - - protected _isColumnVisible(column) { - return super._isColumnVisible(column) && !column.adaptiveHidden; - } - - public getVisibleDataColumnsByBandColumn(bandColumnIndex: number) { - return super.getVisibleDataColumnsByBandColumn(bandColumnIndex) - .filter((column) => column.visibleWidth !== HIDDEN_COLUMNS_WIDTH); - } - - public isAdaptiveHiddenColumn(column: Column): boolean { - return super.isAdaptiveHiddenColumn(column) - || this.adaptiveColumnsController.isColumnHidden(column); - } -}; - -const resizing = (Base: ModuleType) => class AdaptivityResizingControllerExtender extends Base { - public dispose() { - super.dispose.apply(this, arguments as any); - clearTimeout(this._updateScrollableTimeoutID); - } - - private isHiddenColumnsChanged( - oldHiddenColumns: Column[], - hiddenColumns: Column[], - ): boolean { - if (oldHiddenColumns.length !== hiddenColumns.length) { - return true; - } - - const oldIndices = new Set(oldHiddenColumns.map((col) => col.index)); - - return hiddenColumns.some((col) => !oldIndices.has(col.index)); - } - - private updateColumnViewsFirstCellClasses(): void { - COLUMN_VIEWS.forEach((viewName) => { - const view = this.getView(viewName); - - if (view?.isVisible()) { - view.updateFirstCellClasses(); - } - }); - } - - protected _needBestFit() { - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - return super._needBestFit() || !!this.adaptiveColumnsController.getHidingColumnsQueue().length; - } - - protected _correctColumnWidths(resultWidths: (number | string | undefined)[], visibleColumns: Column[]): boolean { - const adaptiveController = this.adaptiveColumnsController; - const oldHiddenColumns = adaptiveController.getHiddenColumns(); - const hidingColumnsQueue = adaptiveController.updateHidingQueue(this._columnsController.getColumns()); - - adaptiveController.hideRedundantColumns(resultWidths, visibleColumns, hidingColumnsQueue); - const hiddenColumns = adaptiveController.getHiddenColumns(); - const isHiddenColumnsChanged = this.isHiddenColumnsChanged(oldHiddenColumns, hiddenColumns); - - if (isHiddenColumnsChanged && adaptiveController.hasAdaptiveDetailRowExpanded()) { - adaptiveController.updateForm(hiddenColumns); - } - - if (isHiddenColumnsChanged) { - this.updateColumnViewsFirstCellClasses(); - } - - if (!hiddenColumns.length) { - adaptiveController.collapseAdaptiveDetailRow(); - } - - return super._correctColumnWidths.apply(this, arguments as any); - } - - protected _toggleBestFitMode(isBestFit) { - this.adaptiveColumnsController._toggleGroupAdaptiveRowVisibility(isBestFit); - isBestFit && this.adaptiveColumnsController._showHiddenColumns(); - super._toggleBestFitMode(isBestFit); - } - - protected _needStretch() { - const { adaptiveColumnsController } = this; - return super._needStretch.apply(this, arguments as any) || adaptiveColumnsController.getHidingColumnsQueue().length || adaptiveColumnsController.hasHiddenColumns(); - } -}; - -const headersKeyboardNavigation = (Base: ModuleType) => class AdaptivityHeadersKeyboardNavigationExtender extends Base { - protected getColumnVisibleIndexCorrection( - visibleIndex: number, - rowIndex: number, - direction: Direction, - ): number { - let indexCorrection = super.getColumnVisibleIndexCorrection(visibleIndex, rowIndex, direction); - let visibleColumns = this._columnsController.getVisibleColumns(rowIndex); - - visibleColumns = direction === 'next' - ? visibleColumns.slice(visibleIndex + 1) - : visibleColumns.slice(0, visibleIndex).reverse(); - - while (visibleColumns?.shift()?.visibleWidth === HIDDEN_COLUMNS_WIDTH) { - indexCorrection += direction === 'next' ? 1 : -1; - } - - return indexCorrection; - } - - protected getFocusableColumns(rowIndex?: number, bandColumnId?: number): Column[] { - return super.getFocusableColumns(rowIndex, bandColumnId) - .filter((col) => col.visibleWidth !== HIDDEN_COLUMNS_WIDTH); - } - - protected getDraggableColumns( - column, - rowIndex: number, - ): any[] { - return super.getDraggableColumns(column, rowIndex) - .filter((col) => col.visibleWidth !== HIDDEN_COLUMNS_WIDTH); - } -}; - -export const adaptivityModule: Module = { - defaultOptions() { - return { - columnHidingEnabled: false, - }; - }, - controllers: { - adaptiveColumns: AdaptiveColumnsController, - }, - extenders: { - views: { - rowsView, - }, - controllers: { - export: exportExtender, - columnsResizer, - draggingHeader, - editing, - resizing, - data, - editorFactory, - columns, - keyboardNavigation, - headersKeyboardNavigation, - }, - }, -}; diff --git a/packages/devextreme/js/__internal/grids/tree_list/module_not_extended/adaptivity.ts b/packages/devextreme/js/__internal/grids/tree_list/module_not_extended/adaptivity.ts index c7afd0fc51d2..8c43dde897d2 100644 --- a/packages/devextreme/js/__internal/grids/tree_list/module_not_extended/adaptivity.ts +++ b/packages/devextreme/js/__internal/grids/tree_list/module_not_extended/adaptivity.ts @@ -1,4 +1,4 @@ -import { adaptivityModule } from '@ts/grids/grid_core/adaptivity/m_adaptivity'; +import { adaptivityModule } from '@ts/grids/grid_core/adaptivity/adaptivity_module'; import treeListCore from '../m_core'; From 8b683676c4390141100ed81340f5ec025356f33a Mon Sep 17 00:00:00 2001 From: Alyar <> Date: Thu, 20 Aug 2026 21:55:50 +0400 Subject: [PATCH 4/4] Grids - Adaptivity module: move export extender to datagrid --- .../data_grid/adaptivity/adaptivity_module.ts | 15 +++++++++++++++ .../adaptivity/extenders/adaptivity_export.ts | 2 +- .../js/__internal/grids/data_grid/m_widget.ts | 2 +- .../data_grid/module_not_extended/adaptivity.ts | 5 ----- .../grid_core/adaptivity/adaptivity_module.ts | 2 -- 5 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 packages/devextreme/js/__internal/grids/data_grid/adaptivity/adaptivity_module.ts rename packages/devextreme/js/__internal/grids/{grid_core => data_grid}/adaptivity/extenders/adaptivity_export.ts (86%) delete mode 100644 packages/devextreme/js/__internal/grids/data_grid/module_not_extended/adaptivity.ts diff --git a/packages/devextreme/js/__internal/grids/data_grid/adaptivity/adaptivity_module.ts b/packages/devextreme/js/__internal/grids/data_grid/adaptivity/adaptivity_module.ts new file mode 100644 index 000000000000..6f3cd68402d1 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/data_grid/adaptivity/adaptivity_module.ts @@ -0,0 +1,15 @@ +import { adaptivityModule } from '@ts/grids/grid_core/adaptivity/adaptivity_module'; + +import gridCore from '../m_core'; +import { adaptivityExportExtender } from './extenders/adaptivity_export'; + +gridCore.registerModule('adaptivity', { + ...adaptivityModule, + extenders: { + ...adaptivityModule.extenders, + controllers: { + ...adaptivityModule.extenders?.controllers, + export: adaptivityExportExtender, + }, + }, +}); diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_export.ts b/packages/devextreme/js/__internal/grids/data_grid/adaptivity/extenders/adaptivity_export.ts similarity index 86% rename from packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_export.ts rename to packages/devextreme/js/__internal/grids/data_grid/adaptivity/extenders/adaptivity_export.ts index f43450e8e5f0..77e59a6531db 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/extenders/adaptivity_export.ts +++ b/packages/devextreme/js/__internal/grids/data_grid/adaptivity/extenders/adaptivity_export.ts @@ -1,7 +1,7 @@ import type { ExportController } from '@ts/grids/data_grid/export/m_export'; import type { ModuleType } from '@ts/grids/grid_core/m_types'; -import { HIDDEN_COLUMNS_WIDTH } from '../const'; +import { HIDDEN_COLUMNS_WIDTH } from '../../../grid_core/adaptivity/const'; export const adaptivityExportExtender = ( Base: ModuleType, diff --git a/packages/devextreme/js/__internal/grids/data_grid/m_widget.ts b/packages/devextreme/js/__internal/grids/data_grid/m_widget.ts index 0c0d20b9a217..773e5bb377c4 100644 --- a/packages/devextreme/js/__internal/grids/data_grid/m_widget.ts +++ b/packages/devextreme/js/__internal/grids/data_grid/m_widget.ts @@ -28,7 +28,7 @@ import './keyboard_navigation/m_group_panel_keyboard_navigation'; import './summary/m_summary'; import './module_not_extended/sticky_columns'; import './module_not_extended/column_fixing'; -import './module_not_extended/adaptivity'; +import './adaptivity/adaptivity_module'; import './module_not_extended/virtual_columns'; import './export/m_export'; import './focus/m_focus'; diff --git a/packages/devextreme/js/__internal/grids/data_grid/module_not_extended/adaptivity.ts b/packages/devextreme/js/__internal/grids/data_grid/module_not_extended/adaptivity.ts deleted file mode 100644 index b8ca0a2f63e3..000000000000 --- a/packages/devextreme/js/__internal/grids/data_grid/module_not_extended/adaptivity.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { adaptivityModule } from '@ts/grids/grid_core/adaptivity/adaptivity_module'; - -import gridCore from '../m_core'; - -gridCore.registerModule('adaptivity', adaptivityModule); diff --git a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/adaptivity_module.ts b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/adaptivity_module.ts index 4dd174693cc0..8ca5dfda64b0 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/adaptivity/adaptivity_module.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/adaptivity/adaptivity_module.ts @@ -5,7 +5,6 @@ import { adaptivityDataControllerExtender } from './extenders/adaptivity_data_co import { adaptivityDraggingHeaderExtender } from './extenders/adaptivity_dragging_header'; import { adaptivityEditingExtender } from './extenders/adaptivity_editing'; import { adaptivityEditorFactoryExtender } from './extenders/adaptivity_editor_factory'; -import { adaptivityExportExtender } from './extenders/adaptivity_export'; import { adaptivityHeadersKeyboardNavigationExtender } from './extenders/adaptivity_headers_keyboard_navigation'; import { adaptivityKeyboardNavigationExtender } from './extenders/adaptivity_keyboard_navigation'; import { adaptivityResizingControllerExtender } from './extenders/adaptivity_resizing_controller'; @@ -26,7 +25,6 @@ export const adaptivityModule: Module = { rowsView: adaptivityRowsViewExtender, }, controllers: { - export: adaptivityExportExtender, columnsResizer: adaptivityColumnsResizerExtender, draggingHeader: adaptivityDraggingHeaderExtender, editing: adaptivityEditingExtender,