From 64b059ec3083c5f01d6aa9ec6bc71bc16d5fb55d Mon Sep 17 00:00:00 2001 From: "anna.shakhova" <68295572+anna-shakhova@users.noreply.github.com> Date: Wed, 9 Sep 2026 15:14:32 +0200 Subject: [PATCH 1/5] Grids: retarget `hasKnownLastPage` method --- .../data_controller/data_controller.ts | 4 - .../__tests__/data_source_controller.test.ts | 13 +++ .../data_source/data_source_controller.ts | 4 + .../__tests__/pager_view.integration.test.ts | 83 +++++++++++++++++++ .../grids/grid_core/pager/m_pager.ts | 12 ++- .../virtual_scrolling_data_controller.ts | 4 +- .../virtual_scrolling/m_virtual_scrolling.ts | 17 ++-- .../testing/helpers/gridBaseMocks.js | 7 +- .../dataController.tests.js | 18 ++-- .../pagerView.tests.js | 2 +- 10 files changed, 132 insertions(+), 32 deletions(-) create mode 100644 packages/devextreme/js/__internal/grids/grid_core/pager/__tests__/pager_view.integration.test.ts 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 6c98e370ae1f..945e4fc40b34 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 @@ -1640,10 +1640,6 @@ export class DataController extends modules.Controller { return (this._dataSource ? this._dataSource.totalItemsCount() : 0); } - public hasKnownLastPage(): boolean { - return (this._dataSource ? this._dataSource.hasKnownLastPage() : true); - } - /** * @extended: state_storing */ diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts b/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts index d64d70ec46ab..5f7ee3e08835 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts @@ -22,6 +22,7 @@ interface AdapterStub { key: jest.Mock<() => StoreKey | undefined>; remoteOperations: jest.Mock<() => RemoteOperationsOptions>; getDataIndexGetter: jest.Mock<() => (data: RawItemData) => number>; + hasKnownLastPage: jest.Mock<() => boolean>; dispose: jest.Mock<(isShared?: boolean) => void>; init: jest.Mock<(dataSource: DataSource) => void>; } @@ -38,6 +39,7 @@ const createAdapterStub = (marker: string): AdapterStub => ({ key: jest.fn(() => marker as StoreKey), remoteOperations: jest.fn(() => ({ filtering: true } as RemoteOperationsOptions)), getDataIndexGetter: jest.fn(() => (): number => 0), + hasKnownLastPage: jest.fn(() => false), dispose: jest.fn(), init: jest.fn(), }); @@ -164,6 +166,10 @@ describe('DataSourceController', () => { expect(createController().getDataIndexGetter()).toBeUndefined(); }); + it('reports the last page as known', () => { + expect(createController().hasKnownLastPage()).toBe(true); + }); + it('returns an empty object from remoteOperations, so callers can enumerate it', () => { const controller = createController(); @@ -209,6 +215,13 @@ describe('DataSourceController', () => { expect(adapter.getDataIndexGetter).toHaveBeenCalledTimes(1); }); + it('delegates hasKnownLastPage to the adapter', () => { + const { controller, adapter } = withAdapter(); + + expect(controller.hasKnownLastPage()).toBe(false); + expect(adapter.hasKnownLastPage).toHaveBeenCalledTimes(1); + }); + it('returns the inner DataSource from getDataSource, not the adapter', () => { const { controller, adapter } = withAdapter(); diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts index 7868bde16226..f6c4217b1487 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts @@ -147,4 +147,8 @@ export class DataSourceController< public getCachedStoreData(): RawItemData[] | undefined { return this.adapter?.getCachedStoreData(); } + + public hasKnownLastPage(): boolean { + return this.adapter ? this.adapter.hasKnownLastPage() : true; + } } diff --git a/packages/devextreme/js/__internal/grids/grid_core/pager/__tests__/pager_view.integration.test.ts b/packages/devextreme/js/__internal/grids/grid_core/pager/__tests__/pager_view.integration.test.ts new file mode 100644 index 000000000000..7f3f61f1dca0 --- /dev/null +++ b/packages/devextreme/js/__internal/grids/grid_core/pager/__tests__/pager_view.integration.test.ts @@ -0,0 +1,83 @@ +import { + afterEach, beforeEach, describe, expect, it, +} from '@jest/globals'; + +import type { DataGridInstance } from '../../__tests__/__mock__/helpers/utils'; +import { + afterTest, + beforeTest, + createDataGrid, +} from '../../__tests__/__mock__/helpers/utils'; + +const ITEMS = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }]; + +interface Pagination { + option: (name: string) => unknown; +} + +const getPagination = (instance: DataGridInstance): Pagination => ( + instance.getView('pagerView') as unknown as { getPager: () => Pagination } +).getPager(); + +const isPagerVisible = (instance: DataGridInstance): boolean => instance + .getView('pagerView') + .isVisible(); + +describe('PagerView', () => { + beforeEach(beforeTest); + afterEach(afterTest); + + describe('without a data source', () => { + it('reports one page and no items', async () => { + const { instance } = await createDataGrid({ + pager: { visible: true }, + }); + + expect(getPagination(instance).option('pageCount')).toBe(1); + expect(getPagination(instance).option('itemCount')).toBe(0); + expect(getPagination(instance).option('hasKnownLastPage')).toBe(true); + }); + + it('is hidden in auto mode', async () => { + const { instance } = await createDataGrid({ + pager: { visible: 'auto' }, + }); + + expect(isPagerVisible(instance)).toBe(false); + }); + }); + + describe('with a data source', () => { + it('reports the page count and the item count', async () => { + const { instance } = await createDataGrid({ + dataSource: ITEMS, + paging: { pageSize: 2 }, + pager: { visible: true }, + }); + + expect(getPagination(instance).option('pageCount')).toBe(3); + expect(getPagination(instance).option('itemCount')).toBe(5); + expect(getPagination(instance).option('hasKnownLastPage')).toBe(true); + }); + + it('is visible in auto mode when there is more than one page', async () => { + const { instance } = await createDataGrid({ + dataSource: ITEMS, + paging: { pageSize: 2 }, + pager: { visible: 'auto' }, + }); + + expect(isPagerVisible(instance)).toBe(true); + }); + + it('is hidden in auto mode when a single page holds every item', async () => { + const { instance } = await createDataGrid({ + dataSource: ITEMS, + paging: { pageSize: 10 }, + pager: { visible: 'auto' }, + }); + + expect(isPagerVisible(instance)).toBe(false); + }); + }); +}); diff --git a/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts b/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts index e645cf17d489..4e33159fa4de 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts @@ -1,6 +1,7 @@ import messageLocalization from '@js/common/core/localization/message'; import { isDefined } from '@js/core/utils/type'; import { hasWindow } from '@js/core/utils/window'; +import type { DataSourceController } from '@ts/grids/grid_core/data_source/data_source_controller'; import Pagination from '@ts/pagination/wrappers/pagination'; import modules from '../m_modules'; @@ -19,9 +20,13 @@ export class PagerView extends modules.View { private _pageSizes: any; + private dataSourceController!: DataSourceController; + public init() { const dataController = this.getController('data'); + this.dataSourceController = this.getController('dataSource'); + dataController.changed.add((e) => { if (e && e.repaintChangesOnly) { const pager = this._pager; @@ -31,7 +36,7 @@ export class PagerView extends modules.View { pageSize: dataController.pageSize(), pageCount: dataController.pageCount(), itemCount: dataController.totalCount(), - hasKnownLastPage: dataController.hasKnownLastPage(), + hasKnownLastPage: this.dataSourceController.hasKnownLastPage(), }); } else { this.render(); @@ -96,7 +101,7 @@ export class PagerView extends modules.View { label: pagerOptions.label, allowedPageSizes: that.getPageSizes(), itemCount: dataController.totalCount(), - hasKnownLastPage: dataController.hasKnownLastPage(), + hasKnownLastPage: that.dataSourceController.hasKnownLastPage(), rtlEnabled: that.option('rtlEnabled'), isGridCompatibilityMode: true, _getParentComponentRootNode: () => this.component.element(), @@ -164,7 +169,8 @@ export class PagerView extends modules.View { if (scrolling && (scrolling.mode === 'virtual' || scrolling.mode === 'infinite')) { pagerVisible = false; } else { - pagerVisible = dataController.pageCount() > 1 || (dataController.isLoaded() && !dataController.hasKnownLastPage()); + pagerVisible = dataController.pageCount() > 1 + || (dataController.isLoaded() && !this.dataSourceController.hasKnownLastPage()); } } return !!pagerVisible; diff --git a/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/extenders/virtual_scrolling_data_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/extenders/virtual_scrolling_data_controller.ts index d85f9fa8473a..2669e0b8e6b8 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/extenders/virtual_scrolling_data_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/extenders/virtual_scrolling_data_controller.ts @@ -205,7 +205,7 @@ export const virtualScrollingDataControllerExtender = ( return that.option(LEGACY_SCROLLING_MODE) === false ? that._itemCount : that._items.filter(isItemCountable).length; }, hasKnownLastPage() { - return that.option(LEGACY_SCROLLING_MODE) === false ? that.hasKnownLastPage() : true; + return that.option(LEGACY_SCROLLING_MODE) === false ? that.dataSourceController.hasKnownLastPage() : true; }, pageIndex(index) { if (index !== undefined) { @@ -671,7 +671,7 @@ export const virtualScrollingDataControllerExtender = ( private _pageIndexIsValid(pageIndex) { let result = true; - if (isInfiniteMode(this) && this.hasKnownLastPage() || isVirtualMode(this)) { + if (isInfiniteMode(this) && this.dataSourceController.hasKnownLastPage() || isVirtualMode(this)) { result = pageIndex * this.pageSize() < this.totalItemsCount(); } diff --git a/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling.ts b/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling.ts index ca5ae364efd4..f1aa08a5c890 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/m_virtual_scrolling.ts @@ -830,19 +830,18 @@ export const rowsView = (Base: ModuleType) => class VirtualScrollingRo } } - private _updateBottomLoading() { - const that = this; - const virtualMode = isVirtualMode(this); - const infiniteMode = isInfiniteMode(this); - const showBottomLoading = !that._dataController.hasKnownLastPage() && that._dataController.isLoaded() && (virtualMode || infiniteMode); - const $contentElement = that._findContentElement(); - const bottomLoadPanelElement = that._findBottomLoadPanel($contentElement); + private _updateBottomLoading(): void { + const showBottomLoading = !this.dataSourceController.hasKnownLastPage() + && this._dataController.isLoaded() + && isVirtualPaging(this); + const $contentElement = this._findContentElement(); + const bottomLoadPanelElement = this._findBottomLoadPanel($contentElement); if (showBottomLoading) { if (!bottomLoadPanelElement) { $('
') - .addClass(that.addWidgetPrefix(BOTTOM_LOAD_PANEL_CLASS)) - .append(that._createComponent($('
'), LoadIndicator, { + .addClass(this.addWidgetPrefix(BOTTOM_LOAD_PANEL_CLASS)) + .append(this._createComponent($('
'), LoadIndicator, { elementAttr: { role: null, 'aria-label': null, diff --git a/packages/devextreme/testing/helpers/gridBaseMocks.js b/packages/devextreme/testing/helpers/gridBaseMocks.js index 36b48f913316..adbedca4f8cf 100644 --- a/packages/devextreme/testing/helpers/gridBaseMocks.js +++ b/packages/devextreme/testing/helpers/gridBaseMocks.js @@ -55,6 +55,9 @@ module.exports = function($, gridCore, columnResizingReordering, domUtils, commo loadingOperationTypes: function() { return undefined; }, + hasKnownLastPage: function() { + return typeUtils.isDefined(options.hasKnownLastPage) ? options.hasKnownLastPage : true; + }, dispose: function() { }, store: function() { @@ -127,10 +130,6 @@ module.exports = function($, gridCore, columnResizingReordering, domUtils, commo return typeUtils.isDefined(options.pageSizes) ? options.pageSizes : []; }, - hasKnownLastPage: function() { - return typeUtils.isDefined(options.hasKnownLastPage) ? options.hasKnownLastPage : true; - }, - updatePagesCount: function(count) { options.pageCount = count; this.changed.fire(); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js index f018d1e4c3f9..ef21f467fd5b 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js @@ -3077,7 +3077,7 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin assert.equal(this.dataController.totalCount(), 7); assert.equal(this.dataController.pageCount(), 2); assert.equal(this.dataController.pageIndex(), 0); - assert.ok(this.dataController.hasKnownLastPage()); + assert.ok(this.dataSourceController.hasKnownLastPage()); assert.deepEqual(this.dataController.items()[0].values, ['Alex', 215]); assert.deepEqual(this.dataController.items()[0].data, { name: 'Alex', pay: 215 }); }); @@ -3337,7 +3337,7 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin assert.equal(this.dataController.pageIndex(), 1); assert.equal(this.dataController.pageCount(), 3); - assert.ok(this.dataController.hasKnownLastPage()); + assert.ok(this.dataSourceController.hasKnownLastPage()); assert.equal(this.dataController.totalCount(), 7); assert.equal(this.dataController.items().length, 3); assert.deepEqual(this.dataController.items()[0].values, ['Dan3', 153]); @@ -5682,7 +5682,7 @@ QUnit.module('Infinite scrolling', { // assert assert.strictEqual(this.dataController.pageIndex(), 0); - assert.strictEqual(this.dataController.hasKnownLastPage(), false); + assert.strictEqual(this.dataSourceController.hasKnownLastPage(), false); assert.strictEqual(this.dataController.items().length, 20); }); @@ -5692,7 +5692,7 @@ QUnit.module('Infinite scrolling', { // assert assert.strictEqual(this.dataController.pageIndex(), 1); - assert.strictEqual(this.dataController.hasKnownLastPage(), false); + assert.strictEqual(this.dataSourceController.hasKnownLastPage(), false); assert.strictEqual(this.dataController.items().length, 40); }); @@ -5712,7 +5712,7 @@ QUnit.module('Infinite scrolling', { // assert assert.strictEqual(loadingCount, 1); assert.strictEqual(this.dataController.pageIndex(), 1); - assert.strictEqual(this.dataController.hasKnownLastPage(), false); + assert.strictEqual(this.dataSourceController.hasKnownLastPage(), false); assert.strictEqual(this.dataController.items().length, 40); }); @@ -5724,7 +5724,7 @@ QUnit.module('Infinite scrolling', { // assert assert.strictEqual(this.dataController.pageIndex(), 1); - assert.strictEqual(this.dataController.hasKnownLastPage(), false); + assert.strictEqual(this.dataSourceController.hasKnownLastPage(), false); assert.strictEqual(this.dataController.items().length, 40); }); @@ -5736,7 +5736,7 @@ QUnit.module('Infinite scrolling', { // assert assert.strictEqual(this.dataController.pageIndex(), 2); - assert.strictEqual(this.dataController.hasKnownLastPage(), true); + assert.strictEqual(this.dataSourceController.hasKnownLastPage(), true); assert.strictEqual(this.dataController.items().length, 50); }); @@ -5764,7 +5764,7 @@ QUnit.module('Infinite scrolling', { // assert assert.strictEqual(this.dataController.pageIndex(), 0); - assert.strictEqual(this.dataController.hasKnownLastPage(), false); + assert.strictEqual(this.dataSourceController.hasKnownLastPage(), false); assert.strictEqual(this.dataController.items().length, 20); }); @@ -9420,7 +9420,7 @@ QUnit.module('Remote Grouping', { assert.strictEqual(storeLoadOptions.requireTotalCount, true, 'requireTotalCount option'); assert.ok(!this.dataController.isLoading()); assert.equal(this.dataController.totalCount(), 10, 'totalCount'); - assert.equal(this.dataController.hasKnownLastPage(), true, 'hasKnownLastPage'); + assert.equal(this.dataSourceController.hasKnownLastPage(), true, 'hasKnownLastPage'); assert.equal(this.dataController.items().length, 2, 'items count'); assert.equal(this.dataController.pageCount(), 5, 'pageCount'); }); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/pagerView.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/pagerView.tests.js index fb87a2844f8e..3220bd37480a 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/pagerView.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/pagerView.tests.js @@ -443,7 +443,7 @@ QUnit.module('Pager', { const isVisible = pagerView.isVisible(); // assert - assert.ok(!this.dataController.hasKnownLastPage()); + assert.ok(!this.dataSourceController.hasKnownLastPage()); assert.equal(this.dataController.pageCount(), 1); assert.ok(isVisible); }); From 23e8867082c3e14a8ccc903215e3c703afacf781 Mon Sep 17 00:00:00 2001 From: "anna.shakhova" <68295572+anna-shakhova@users.noreply.github.com> Date: Wed, 9 Sep 2026 15:24:28 +0200 Subject: [PATCH 2/5] Grids: retarget `totalItemsCount` method --- .../data_controller/data_controller.ts | 4 ---- .../__tests__/data_source_controller.test.ts | 13 +++++++++++++ .../data_source/data_source_controller.ts | 4 ++++ .../m_keyboard_navigation.ts | 2 +- .../grids/grid_core/views/m_grid_view.ts | 6 +++++- .../virtual_scrolling_data_controller.ts | 6 +++--- .../testing/helpers/gridBaseMocks.js | 7 +++---- .../dataController.tests.js | 18 +++++++++--------- .../dataController.tests.js | 8 ++++---- 9 files changed, 42 insertions(+), 26 deletions(-) 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 945e4fc40b34..22b45549052e 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 @@ -1636,10 +1636,6 @@ export class DataController extends modules.Controller { return (this._dataSource ? this._dataSource.itemsCount() : 0); } - public totalItemsCount(): number { - return (this._dataSource ? this._dataSource.totalItemsCount() : 0); - } - /** * @extended: state_storing */ diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts b/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts index 5f7ee3e08835..a806687e3d18 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts @@ -23,6 +23,7 @@ interface AdapterStub { remoteOperations: jest.Mock<() => RemoteOperationsOptions>; getDataIndexGetter: jest.Mock<() => (data: RawItemData) => number>; hasKnownLastPage: jest.Mock<() => boolean>; + totalItemsCount: jest.Mock<() => number>; dispose: jest.Mock<(isShared?: boolean) => void>; init: jest.Mock<(dataSource: DataSource) => void>; } @@ -40,6 +41,7 @@ const createAdapterStub = (marker: string): AdapterStub => ({ remoteOperations: jest.fn(() => ({ filtering: true } as RemoteOperationsOptions)), getDataIndexGetter: jest.fn(() => (): number => 0), hasKnownLastPage: jest.fn(() => false), + totalItemsCount: jest.fn(() => 42), dispose: jest.fn(), init: jest.fn(), }); @@ -170,6 +172,10 @@ describe('DataSourceController', () => { expect(createController().hasKnownLastPage()).toBe(true); }); + it('counts no items', () => { + expect(createController().totalItemsCount()).toBe(0); + }); + it('returns an empty object from remoteOperations, so callers can enumerate it', () => { const controller = createController(); @@ -222,6 +228,13 @@ describe('DataSourceController', () => { expect(adapter.hasKnownLastPage).toHaveBeenCalledTimes(1); }); + it('delegates totalItemsCount to the adapter', () => { + const { controller, adapter } = withAdapter(); + + expect(controller.totalItemsCount()).toBe(42); + expect(adapter.totalItemsCount).toHaveBeenCalledTimes(1); + }); + it('returns the inner DataSource from getDataSource, not the adapter', () => { const { controller, adapter } = withAdapter(); diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts index f6c4217b1487..273f2870cb2c 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts @@ -151,4 +151,8 @@ export class DataSourceController< public hasKnownLastPage(): boolean { return this.adapter ? this.adapter.hasKnownLastPage() : true; } + + public totalItemsCount(): number { + return this.adapter ? this.adapter.totalItemsCount() : 0; + } } 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 9564e9d39939..85683103b999 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 @@ -1463,7 +1463,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo private getFirstOrLastRowIndex(needFirstRow: boolean): number { const rowCount = this._isVirtualScrolling() - ? this._dataController.totalItemsCount() + ? this.dataSourceController.totalItemsCount() : this._dataController.items(true)?.length; return needFirstRow ? 0 : rowCount - 1; 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 2a671b7f1434..8f0573b7488c 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 @@ -23,6 +23,7 @@ import type { ColumnHeadersView } from '../column_headers/m_column_headers'; import type { ColumnsController } from '../columns_controller/m_columns_controller'; import type { DataController } from '../data_controller/data_controller'; import type { DataChange } from '../data_controller/types'; +import type { DataSourceController } from '../data_source/data_source_controller'; import modules from '../m_modules'; import gridCoreUtils from '../m_utils'; import type { RowsView } from './m_rows_view'; @@ -89,6 +90,8 @@ export class ResizingController extends modules.ViewController { public _dataController!: DataController; + private dataSourceController!: DataSourceController; + protected _rowsView!: RowsView; private _columnHeadersView!: ColumnHeadersView; @@ -130,6 +133,7 @@ export class ResizingController extends modules.ViewController { public init() { this._prevContentMinHeight = null; this._dataController = this.getController('data'); + this.dataSourceController = this.getController('dataSource'); this._columnsController = this.getController('columns'); this._columnHeadersView = this.getView('columnHeadersView'); this.adaptiveColumnsController = this.getController('adaptiveColumns'); @@ -231,7 +235,7 @@ export class ResizingController extends modules.ViewController { let labelParts: string[] = []; const columnCount = this._columnsController?._columns?.filter(({ visible }) => !!visible).length ?? 0; - const totalItemsCount = Math.max(0, this._dataController.totalItemsCount()); + const totalItemsCount = Math.max(0, this.dataSourceController.totalItemsCount()); const widgetAriaLabel = this._getWidgetAriaLabel(); widgetStatusText = messageLocalization // @ts-expect-error Badly typed format method diff --git a/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/extenders/virtual_scrolling_data_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/extenders/virtual_scrolling_data_controller.ts index 2669e0b8e6b8..859bd19ade8d 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/extenders/virtual_scrolling_data_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/extenders/virtual_scrolling_data_controller.ts @@ -199,7 +199,7 @@ export const virtualScrollingDataControllerExtender = ( }, totalItemsCount() { if (isVirtualPaging(that)) { - return that.totalItemsCount(); + return that.dataSourceController.totalItemsCount(); } return that.option(LEGACY_SCROLLING_MODE) === false ? that._itemCount : that._items.filter(isItemCountable).length; @@ -672,7 +672,7 @@ export const virtualScrollingDataControllerExtender = ( let result = true; if (isInfiniteMode(this) && this.dataSourceController.hasKnownLastPage() || isVirtualMode(this)) { - result = pageIndex * this.pageSize() < this.totalItemsCount(); + result = pageIndex * this.pageSize() < this.dataSourceController.totalItemsCount(); } return result; @@ -681,7 +681,7 @@ export const virtualScrollingDataControllerExtender = ( private isAllLoadedInAppendMode(): boolean { const loadedItemCount = this.pageSize() * (this._dataSource?.loadPageCount() ?? 0); - return isInfiniteMode(this) && this.totalItemsCount() < loadedItemCount; + return isInfiniteMode(this) && this.dataSourceController.totalItemsCount() < loadedItemCount; } // T1326786: the grid is scrolled to paging.pageIndex on the first resize only, diff --git a/packages/devextreme/testing/helpers/gridBaseMocks.js b/packages/devextreme/testing/helpers/gridBaseMocks.js index adbedca4f8cf..232b694bb2c0 100644 --- a/packages/devextreme/testing/helpers/gridBaseMocks.js +++ b/packages/devextreme/testing/helpers/gridBaseMocks.js @@ -58,6 +58,9 @@ module.exports = function($, gridCore, columnResizingReordering, domUtils, commo hasKnownLastPage: function() { return typeUtils.isDefined(options.hasKnownLastPage) ? options.hasKnownLastPage : true; }, + totalItemsCount: function() { + return options.totalItemsCount; + }, dispose: function() { }, store: function() { @@ -223,10 +226,6 @@ module.exports = function($, gridCore, columnResizingReordering, domUtils, commo return options.itemsCount; }, - totalItemsCount: function() { - return options.totalItemsCount; - }, - isLoading: function() { return false; }, diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js index ef21f467fd5b..2abba5d53558 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js @@ -2848,7 +2848,7 @@ QUnit.module('No dataSource', { beforeEach: setupModule, afterEach: teardownModu QUnit.test('getters', function(assert) { assert.strictEqual(this.dataController.items().length, 0); - assert.strictEqual(this.dataController.totalItemsCount(), 0); + assert.strictEqual(this.dataSourceController.totalItemsCount(), 0); assert.strictEqual(this.dataController.pageCount(), 1); assert.strictEqual(this.dataController.pageIndex(), 0); assert.strictEqual(this.dataController.pageSize(), 0); @@ -3606,7 +3606,7 @@ QUnit.module('Virtual scrolling', { beforeEach: setupVirtualScrollingModule, aft }); QUnit.test('getAllRowsCount for virtual scrolling', function(assert) { - assert.strictEqual(this.dataController.totalItemsCount(), 1000); + assert.strictEqual(this.dataSourceController.totalItemsCount(), 1000); }); // T308521 @@ -3958,7 +3958,7 @@ QUnit.module('Virtual rendering', { beforeEach: setupVirtualRenderingModule, aft const rowsScrollController = this.dataController._rowsScrollController; const defaultItemSize = rowsScrollController.getItemSize(); - const bottomPosition = (this.dataController.totalItemsCount() - this.dataController.viewportSize()) * defaultItemSize; + const bottomPosition = (this.dataSourceController.totalItemsCount() - this.dataController.viewportSize()) * defaultItemSize; // act this.dataController.setViewportPosition(bottomPosition); @@ -14296,7 +14296,7 @@ QUnit.module('Using DataSource instance', { assert.deepEqual(changes, ['columns', 'data']); assert.equal(this.dataController.itemsCount(), 5); - assert.equal(this.dataController.totalItemsCount(), 8); + assert.equal(this.dataSourceController.totalItemsCount(), 8); assert.equal(this.dataController.items()[0].rowType, 'group'); assert.equal(this.dataController.items()[1].rowType, 'data'); assert.equal(this.dataController.items()[1].data.field3, 3); @@ -14338,7 +14338,7 @@ QUnit.module('Using DataSource instance', { assert.deepEqual(changes, ['columns', 'data']); assert.equal(this.dataController.itemsCount(), 5); - assert.equal(this.dataController.totalItemsCount(), 5); + assert.equal(this.dataSourceController.totalItemsCount(), 5); assert.equal(this.dataController.items()[0].data.field3, 7); assert.equal(this.dataController.items()[4].data.field3, 3); }); @@ -14373,7 +14373,7 @@ QUnit.module('Using DataSource instance', { this.clock.tick(10); // assert - assert.equal(this.dataController.totalItemsCount(), 3); + assert.equal(this.dataSourceController.totalItemsCount(), 3); assert.equal(this.dataController.items().length, 3); // act @@ -14381,7 +14381,7 @@ QUnit.module('Using DataSource instance', { this.clock.tick(10); // assert - assert.equal(this.dataController.totalItemsCount(), 5); + assert.equal(this.dataSourceController.totalItemsCount(), 5); assert.equal(this.dataController.items().length, 5); const spy = sinon.spy(); @@ -14392,7 +14392,7 @@ QUnit.module('Using DataSource instance', { this.clock.tick(10); // assert - assert.equal(this.dataController.totalItemsCount(), 3); + assert.equal(this.dataSourceController.totalItemsCount(), 3); assert.equal(this.dataController.items().length, 3); assert.equal(this.dataController.pageIndex(), 0); assert.equal(this.dataSource.pageIndex(), 0); @@ -14420,7 +14420,7 @@ QUnit.module('Using DataSource instance', { // assert assert.equal(this.columnsController.getGroupColumns().length, 1, 'grouped columns count'); assert.deepEqual(this.dataSourceController.getAdapter().group(), [{ selector: 'field1', desc: false, isExpanded: false }], 'dataSource group when autoExpandAll false'); - assert.equal(this.dataController.totalItemsCount(), 2); + assert.equal(this.dataSourceController.totalItemsCount(), 2); assert.equal(this.dataController.items().length, 2); }); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/dataController.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/dataController.tests.js index 7084f5faf6d2..4717a4262bcb 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/dataController.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/dataController.tests.js @@ -486,7 +486,7 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod }); // assert - assert.equal(this.dataController.totalItemsCount(), 4, 'totalItemsCount'); + assert.equal(this.dataSourceController.totalItemsCount(), 4, 'totalItemsCount'); const items = this.dataController.items(); assert.equal(items.length, 3, 'count items'); @@ -517,7 +517,7 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod }); // assert - assert.equal(this.dataController.totalItemsCount(), 5, 'totalItemsCount'); + assert.equal(this.dataSourceController.totalItemsCount(), 5, 'totalItemsCount'); assert.equal(this.getVisibleRows().length, 2, 'row count'); assert.strictEqual(this.getVisibleRows()[0].node, this.getNodeByKey(1), 'first node instance is correct'); }); @@ -545,7 +545,7 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod this.expandRow(2); // assert - assert.equal(this.dataController.totalItemsCount(), 5, 'totalItemsCount'); + assert.equal(this.dataSourceController.totalItemsCount(), 5, 'totalItemsCount'); const items = this.dataController.items(); assert.equal(items.length, 3, 'count items'); @@ -568,7 +568,7 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod this.dataController.load(); // assert - assert.equal(this.dataController.totalItemsCount(), 1, 'count visible items'); + assert.equal(this.dataSourceController.totalItemsCount(), 1, 'count visible items'); assert.equal(this.dataController.totalCount(), 3, 'count all items'); }); From 0efdd89225127a83245a03d0552727410020f1da Mon Sep 17 00:00:00 2001 From: "anna.shakhova" <68295572+anna-shakhova@users.noreply.github.com> Date: Wed, 9 Sep 2026 15:35:49 +0200 Subject: [PATCH 3/5] Grids: retarget `totalCount` method --- .../ai_assistant_integration_controller.ts | 2 +- .../data_controller/data_controller.ts | 5 --- ...data_source_controller.integration.test.ts | 8 ++++ .../__tests__/data_source_controller.test.ts | 10 +++++ .../data_source/data_source_controller.ts | 6 ++- .../grids/grid_core/focus/m_focus.ts | 2 +- .../grids/grid_core/pager/m_pager.ts | 4 +- .../grids/grid_core/selection/m_selection.ts | 2 +- .../grids/grid_core/views/m_rows_view.ts | 2 +- .../testing/helpers/gridBaseMocks.js | 7 ++- .../dataController.tests.js | 44 +++++++++---------- .../selection.tests.js | 2 +- .../dataController.tests.js | 2 +- 13 files changed, 56 insertions(+), 40 deletions(-) diff --git a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_integration_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_integration_controller.ts index 742073e23aab..3cb822bb81d2 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_integration_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_integration_controller.ts @@ -57,7 +57,7 @@ export class AIAssistantIntegrationController extends Controller { paging: { pageIndex: this.dataController.pageIndex(), pageSize: this.dataController.pageSize(), - totalCount: this.dataController.totalCount(), + totalCount: this.dataSourceController.totalCount(), visibleRowCount: this.dataController .getVisibleRows() .filter((row) => row.rowType === 'data') 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 22b45549052e..7b3b4a23d312 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 @@ -209,7 +209,6 @@ export class DataController extends modules.Controller { 'pageSize', 'refresh', 'repaintRows', - 'totalCount', ]; } @@ -1643,10 +1642,6 @@ export class DataController extends modules.Controller { return (this._dataSource ? this._dataSource.isLoaded() : true); } - public totalCount(): number { - return (this._dataSource ? this._dataSource.totalCount() : 0); - } - public hasLoadOperation(): boolean { const operationTypes = this._dataSource?.operationTypes() ?? {}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.integration.test.ts b/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.integration.test.ts index 47b9ae87e9ba..3a31f250a03f 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.integration.test.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.integration.test.ts @@ -57,6 +57,14 @@ describe('dataSource module registration', () => { .toBe(instance.getController('dataSource').keyOf(DATA[1])); }); + it('owns the totalCount widget method', async () => { + const { instance } = await createDataGrid({ dataSource: DATA }); + + expect(instance.totalCount()).toBe(DATA.length); + expect(instance.totalCount()) + .toBe(instance.getController('dataSource').totalCount()); + }); + it('sits at the bottom of the controller order', async () => { const { instance } = await createDataGrid({ dataSource: DATA }); diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts b/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts index a806687e3d18..09632b74d726 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts @@ -24,6 +24,7 @@ interface AdapterStub { getDataIndexGetter: jest.Mock<() => (data: RawItemData) => number>; hasKnownLastPage: jest.Mock<() => boolean>; totalItemsCount: jest.Mock<() => number>; + totalCount: jest.Mock<() => number>; dispose: jest.Mock<(isShared?: boolean) => void>; init: jest.Mock<(dataSource: DataSource) => void>; } @@ -42,6 +43,7 @@ const createAdapterStub = (marker: string): AdapterStub => ({ getDataIndexGetter: jest.fn(() => (): number => 0), hasKnownLastPage: jest.fn(() => false), totalItemsCount: jest.fn(() => 42), + totalCount: jest.fn(() => 99), dispose: jest.fn(), init: jest.fn(), }); @@ -174,6 +176,7 @@ describe('DataSourceController', () => { it('counts no items', () => { expect(createController().totalItemsCount()).toBe(0); + expect(createController().totalCount()).toBe(0); }); it('returns an empty object from remoteOperations, so callers can enumerate it', () => { @@ -235,6 +238,13 @@ describe('DataSourceController', () => { expect(adapter.totalItemsCount).toHaveBeenCalledTimes(1); }); + it('delegates totalCount to the adapter', () => { + const { controller, adapter } = withAdapter(); + + expect(controller.totalCount()).toBe(99); + expect(adapter.totalCount).toHaveBeenCalledTimes(1); + }); + it('returns the inner DataSource from getDataSource, not the adapter', () => { const { controller, adapter } = withAdapter(); diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts index 273f2870cb2c..7f7cf610ab26 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts @@ -28,7 +28,7 @@ export class DataSourceController< } public publicMethods(): string[] { - return ['getDataSource', 'keyOf']; + return ['getDataSource', 'keyOf', 'totalCount']; } /** @@ -155,4 +155,8 @@ export class DataSourceController< public totalItemsCount(): number { return this.adapter ? this.adapter.totalItemsCount() : 0; } + + public totalCount(): number { + return this.adapter ? this.adapter.totalCount() : 0; + } } diff --git a/packages/devextreme/js/__internal/grids/grid_core/focus/m_focus.ts b/packages/devextreme/js/__internal/grids/grid_core/focus/m_focus.ts index 91bc8a1cc790..77e11dc293af 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/focus/m_focus.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/focus/m_focus.ts @@ -288,7 +288,7 @@ export class FocusController extends core.ViewController { const offset = rowsScrollController.getItemOffset(focusedRowIndex); const triggerUpdateFocusedRow = () => { - if (this.getDataController().totalCount() && !this.getDataController().items().length) { + if (this.getDataSourceController().totalCount() && !this.getDataController().items().length) { return; } this.component.off('contentReady', triggerUpdateFocusedRow); diff --git a/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts b/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts index 4e33159fa4de..5929f9e6cd31 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts @@ -35,7 +35,7 @@ export class PagerView extends modules.View { pageIndex: getPageIndex(dataController), pageSize: dataController.pageSize(), pageCount: dataController.pageCount(), - itemCount: dataController.totalCount(), + itemCount: this.dataSourceController.totalCount(), hasKnownLastPage: this.dataSourceController.hasKnownLastPage(), }); } else { @@ -100,7 +100,7 @@ export class PagerView extends modules.View { showNavigationButtons: pagerOptions.showNavigationButtons, label: pagerOptions.label, allowedPageSizes: that.getPageSizes(), - itemCount: dataController.totalCount(), + itemCount: that.dataSourceController.totalCount(), hasKnownLastPage: that.dataSourceController.hasKnownLastPage(), rtlEnabled: that.option('rtlEnabled'), isGridCompatibilityMode: true, diff --git a/packages/devextreme/js/__internal/grids/grid_core/selection/m_selection.ts b/packages/devextreme/js/__internal/grids/grid_core/selection/m_selection.ts index c3b0f1b197ad..7c1288a0dc91 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/selection/m_selection.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/selection/m_selection.ts @@ -263,7 +263,7 @@ export class SelectionController extends modules.Controller { filter() { return dataController.getCombinedFilter(deferred); }, - totalCount: () => dataController.totalCount(), + totalCount: () => dataSourceController.totalCount(), getLoadOptions(loadItemIndex, focusedItemIndex, shiftItemIndex) { const { sort, filter } = dataSourceController.lastLoadOptions(); let minIndex = Math.min(loadItemIndex, focusedItemIndex); diff --git a/packages/devextreme/js/__internal/grids/grid_core/views/m_rows_view.ts b/packages/devextreme/js/__internal/grids/grid_core/views/m_rows_view.ts index 353679598357..9a27028aaa2e 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/views/m_rows_view.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/views/m_rows_view.ts @@ -1004,7 +1004,7 @@ export class RowsView extends ColumnsView { const contentElement = this._findContentElement(); const freeSpaceRowElements = this._getFreeSpaceRowElements($table); - if (freeSpaceRowElements && contentElement && dataController.totalCount() >= 0) { + if (freeSpaceRowElements && contentElement && this.dataSourceController.totalCount() >= 0) { let isFreeSpaceRowVisible = false; if (itemCount > 0) { diff --git a/packages/devextreme/testing/helpers/gridBaseMocks.js b/packages/devextreme/testing/helpers/gridBaseMocks.js index 232b694bb2c0..8b089d748c03 100644 --- a/packages/devextreme/testing/helpers/gridBaseMocks.js +++ b/packages/devextreme/testing/helpers/gridBaseMocks.js @@ -61,6 +61,9 @@ module.exports = function($, gridCore, columnResizingReordering, domUtils, commo totalItemsCount: function() { return options.totalItemsCount; }, + totalCount: function() { + return options.totalCount || 0; + }, dispose: function() { }, store: function() { @@ -142,10 +145,6 @@ module.exports = function($, gridCore, columnResizingReordering, domUtils, commo return options.pageCount; }, - totalCount: function() { - return options.totalCount || 0; - }, - pageIndex: function(index) { if(typeUtils.isDefined(index)) { options.pageIndex = index; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js index 2abba5d53558..66a5c92e826f 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js @@ -3074,7 +3074,7 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin this.dataSource.load(); assert.equal(this.dataController.items().length, 5); - assert.equal(this.dataController.totalCount(), 7); + assert.equal(this.dataSourceController.totalCount(), 7); assert.equal(this.dataController.pageCount(), 2); assert.equal(this.dataController.pageIndex(), 0); assert.ok(this.dataSourceController.hasKnownLastPage()); @@ -3098,7 +3098,7 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin // assert assert.equal(changedCount, 1); assert.equal(this.dataController.items().length, 1); - assert.equal(this.dataController.totalCount(), 1); + assert.equal(this.dataSourceController.totalCount(), 1); assert.equal(this.dataController.pageCount(), 1); assert.equal(this.dataController.pageIndex(), 0); assert.deepEqual(this.dataController.items()[0].values, ['Dan3', 153]); @@ -3319,7 +3319,7 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin this.dataSource.reload(true); assert.equal(this.dataController.pageIndex(), 0); - assert.equal(this.dataController.totalCount(), 11); + assert.equal(this.dataSourceController.totalCount(), 11); assert.equal(this.dataController.pageCount(), 3); assert.equal(changedCount, 1, 'changed raise after reload'); }); @@ -3338,7 +3338,7 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin assert.equal(this.dataController.pageIndex(), 1); assert.equal(this.dataController.pageCount(), 3); assert.ok(this.dataSourceController.hasKnownLastPage()); - assert.equal(this.dataController.totalCount(), 7); + assert.equal(this.dataSourceController.totalCount(), 7); assert.equal(this.dataController.items().length, 3); assert.deepEqual(this.dataController.items()[0].values, ['Dan3', 153]); }); @@ -9334,7 +9334,7 @@ QUnit.module('Remote Grouping', { assert.strictEqual(storeLoadOptions.take, undefined, 'no take option'); assert.deepEqual(storeLoadOptions.group, [{ selector: 'name', desc: false, isExpanded: false }], 'group option'); - assert.equal(this.dataController.totalCount(), -1, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), -1, 'totalCount'); assert.equal(this.dataController.pageCount(), 1, 'pageCount'); }); @@ -9379,7 +9379,7 @@ QUnit.module('Remote Grouping', { assert.strictEqual(storeLoadOptions.take, undefined, 'no take option'); assert.deepEqual(storeLoadOptions.group, [{ selector: 'name', desc: false, isExpanded: false }], 'group option'); - assert.equal(this.dataController.totalCount(), -1, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), -1, 'totalCount'); assert.equal(this.dataController.pageCount(), 1, 'pageCount'); }); @@ -9419,7 +9419,7 @@ QUnit.module('Remote Grouping', { assert.strictEqual(storeLoadOptions.take, 2, 'take option'); assert.strictEqual(storeLoadOptions.requireTotalCount, true, 'requireTotalCount option'); assert.ok(!this.dataController.isLoading()); - assert.equal(this.dataController.totalCount(), 10, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 10, 'totalCount'); assert.equal(this.dataSourceController.hasKnownLastPage(), true, 'hasKnownLastPage'); assert.equal(this.dataController.items().length, 2, 'items count'); assert.equal(this.dataController.pageCount(), 5, 'pageCount'); @@ -9449,7 +9449,7 @@ QUnit.module('Remote Grouping', { this.clock.tick(10); // assert - assert.equal(this.dataController.totalCount(), 2, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 2, 'totalCount'); assert.equal(this.dataController.pageCount(), 1, 'pageCount'); assert.deepEqual(this.dataController.items()[0].rowType, 'group', 'item 1 rowType'); assert.deepEqual(this.dataController.items()[0].key, ['1980/10/15'], 'item 1 key'); @@ -9605,7 +9605,7 @@ QUnit.module('Summary', { assert.strictEqual(storeLoadOptions.take, 2, 'take option'); assert.deepEqual(storeLoadOptions.totalSummary, [{ selector: 'age', summaryType: 'custom' }], 'totalSummary option'); assert.ok(!this.dataController.isLoading()); - assert.equal(this.dataController.totalCount(), 10, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 10, 'totalCount'); assert.deepEqual(this.dataController.footerItems(), [{ rowType: 'totalFooter', summaryCells: [[], [{ value: 3, @@ -9701,7 +9701,7 @@ QUnit.module('Summary', { assert.strictEqual(storeLoadOptions.take, 2, 'take option'); assert.deepEqual(storeLoadOptions.totalSummary, [{ selector: 'age', summaryType: 'custom' }], 'totalSummary option'); assert.ok(!this.dataController.isLoading()); - assert.equal(this.dataController.totalCount(), 10, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 10, 'totalCount'); assert.deepEqual(this.dataController.footerItems(), [{ rowType: 'totalFooter', summaryCells: [[], [{ value: 3, @@ -9783,7 +9783,7 @@ QUnit.module('Summary', { assert.strictEqual(storeLoadOptions.take, 2, 'take option'); assert.deepEqual(storeLoadOptions.totalSummary, [{ selector: 'age', summaryType: 'min' }], 'summary totalItems option'); assert.ok(!this.dataController.isLoading()); - assert.equal(this.dataController.totalCount(), 10, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 10, 'totalCount'); assert.deepEqual(this.dataController.footerItems(), [{ rowType: 'totalFooter', summaryCells: [[], [{ column: 'age', @@ -9845,7 +9845,7 @@ QUnit.module('Summary', { assert.deepEqual(storeLoadOptions.totalSummary, [{ selector: 'age', summaryType: 'min' }], 'summary totalItems option'); assert.deepEqual(storeLoadOptions.groupSummary, undefined, 'summary groupItems option'); assert.ok(!this.dataController.isLoading()); - assert.equal(this.dataController.totalCount(), 4, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 4, 'totalCount'); assert.equal(this.dataController.pageCount(), 4, 'pageCount'); assert.deepEqual(this.dataController.items().length, 2); assert.deepEqual(this.dataController.items()[0].data, { @@ -9918,7 +9918,7 @@ QUnit.module('Summary', { assert.deepEqual(storeLoadOptions.totalSummary, [{ selector: 'age', summaryType: 'min' }], 'summary totalItems option'); assert.deepEqual(storeLoadOptions.groupSummary, undefined, 'summary groupItems option'); assert.ok(!this.dataController.isLoading()); - assert.equal(this.dataController.totalCount(), 4, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 4, 'totalCount'); assert.equal(this.dataController.pageCount(), 4, 'pageCount'); assert.deepEqual(this.dataController.items().length, 2); assert.deepEqual(this.dataController.items()[0].data, { @@ -9986,7 +9986,7 @@ QUnit.module('Summary', { assert.deepEqual(storeLoadOptions.totalSummary, [{ selector: 'age', summaryType: 'min' }], 'summary totalItems option'); assert.deepEqual(storeLoadOptions.groupSummary, undefined, 'summary groupItems option'); assert.ok(!this.dataController.isLoading()); - assert.equal(this.dataController.totalCount(), 10, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 10, 'totalCount'); assert.equal(this.dataController.pageCount(), 5, 'pageCount'); assert.deepEqual(this.dataController.items().length, 3); assert.deepEqual(this.dataController.items()[0].data, { @@ -10045,7 +10045,7 @@ QUnit.module('Summary', { assert.strictEqual(storeLoadOptions.take, 2, 'take option'); assert.deepEqual(storeLoadOptions.totalSummary, [{ selector: 'age', summaryType: 'min' }, { selector: 'date', summaryType: 'max' }], 'summary totalItems option'); assert.ok(!this.dataController.isLoading()); - assert.equal(this.dataController.totalCount(), 10, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 10, 'totalCount'); assert.deepEqual(this.dataController.footerItems(), [{ rowType: 'totalFooter', summaryCells: [[], [{ value: 3, @@ -10107,7 +10107,7 @@ QUnit.module('Summary', { assert.deepEqual(storeLoadOptions.totalSummary, [{ selector: 'age', summaryType: 'min' }], 'summary totalItems option'); assert.deepEqual(storeLoadOptions.groupSummary, [{ selector: 'age', summaryType: 'count' }], 'summary groupItems option'); assert.ok(!this.dataController.isLoading()); - assert.equal(this.dataController.totalCount(), 2, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 2, 'totalCount'); assert.equal(this.dataController.pageCount(), 1, 'pageCount'); assert.deepEqual(this.dataController.items()[0].summaryCells, [[], [{ column: 'age', @@ -10172,7 +10172,7 @@ QUnit.module('Summary', { assert.deepEqual(storeLoadOptions.totalSummary, [{ selector: 'age', summaryType: 'min' }], 'summary totalItems option'); assert.deepEqual(storeLoadOptions.groupSummary, [{ selector: 'age', summaryType: 'count' }], 'summary groupItems option'); assert.ok(!this.dataController.isLoading()); - assert.equal(this.dataController.totalCount(), 2, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 2, 'totalCount'); assert.equal(this.dataController.pageCount(), 1, 'pageCount'); assert.deepEqual(this.dataController.items()[0].summaryCells, [[], [{ column: 'age', @@ -10241,7 +10241,7 @@ QUnit.module('Summary', { assert.strictEqual(storeLoadOptions.take, undefined, 'no take option'); assert.deepEqual(storeLoadOptions.filter, [['group', '=', 'Group1'], 'or', ['group', '=', 'Group0']], 'filter option'); assert.deepEqual(storeLoadOptions.sort, [{ 'desc': false, 'isExpanded': true, 'selector': 'group' }], 'sort option'); - assert.equal(this.dataController.totalCount(), 3, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 3, 'totalCount'); assert.equal(this.dataController.pageCount(), 2, 'pageCount'); const items = this.dataController.items(); assert.equal(items.length, 4, 'item count'); @@ -10367,7 +10367,7 @@ QUnit.module('Summary', { [[['group1', '=', 'Group1'], 'and', ['group2', '=', 'Group1_0']], 'or', [['group1', '=', 'Group0'], 'and', ['group2', '=', 'Group0_0']]], 'filter option'); assert.deepEqual(storeLoadOptions.sort, [{ 'desc': false, 'isExpanded': true, 'selector': 'group1' }, { 'desc': false, 'isExpanded': true, 'selector': 'group2' }], 'sort option'); - assert.equal(this.dataController.totalCount(), 3, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 3, 'totalCount'); assert.equal(this.dataController.pageCount(), 2, 'pageCount'); const items = this.dataController.items(); assert.equal(items.length, 6, 'item count'); @@ -14248,7 +14248,7 @@ QUnit.module('Using DataSource instance', { // assert assert.ok(!this.dataSource.filter(), 'no filter'); assert.equal(this.dataController.itemsCount(), 3); - assert.equal(this.dataController.totalCount(), 3); + assert.equal(this.dataSourceController.totalCount(), 3); // act this.dataSource.filter(['field1', '=', 2]); @@ -14260,7 +14260,7 @@ QUnit.module('Using DataSource instance', { assert.deepEqual(this.dataSource.filter(), [filter[0], '=', 2], 'changed filter'); assert.equal(this.dataController.items()[0].data.field3, 6); assert.equal(this.dataController.itemsCount(), 2); - assert.equal(this.dataController.totalCount(), 2); + assert.equal(this.dataSourceController.totalCount(), 2); }); QUnit.test('change group', function(assert) { @@ -14441,7 +14441,7 @@ QUnit.module('Using DataSource instance', { // assert assert.equal(this.dataController.items().length, 3, 'items count'); - assert.equal(this.dataController.totalCount(), 5, 'total count'); + assert.equal(this.dataSourceController.totalCount(), 5, 'total count'); assert.equal(this.dataController.pageCount(), 2, 'page count'); }); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/selection.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/selection.tests.js index 104f13b7c870..b698e348456f 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/selection.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/selection.tests.js @@ -2607,7 +2607,7 @@ QUnit.module('Selection SelectAllMode', { // assert assert.equal(this.array.length, 0, 'array length'); assert.equal(this.dataController.items().length, 0, 'items count'); - assert.equal(this.dataController.totalCount(), 0, 'totalCount'); + assert.equal(this.dataSourceController.totalCount(), 0, 'totalCount'); }); QUnit.test('Select All for multiple selection change page', function(assert) { diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/dataController.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/dataController.tests.js index 4717a4262bcb..a8cc8b81c41f 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/dataController.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.treeList/dataController.tests.js @@ -569,7 +569,7 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod // assert assert.equal(this.dataSourceController.totalItemsCount(), 1, 'count visible items'); - assert.equal(this.dataController.totalCount(), 3, 'count all items'); + assert.equal(this.dataSourceController.totalCount(), 3, 'count all items'); }); QUnit.test('Getting key when there are keyExpr and store hasn\'t key', function(assert) { From 99bde8e2f9f6b6b96752f3dfc53a94f89a8630c1 Mon Sep 17 00:00:00 2001 From: "anna.shakhova" <68295572+anna-shakhova@users.noreply.github.com> Date: Wed, 9 Sep 2026 16:27:41 +0200 Subject: [PATCH 4/5] Grids: retarget `pageCount` method --- .../grid_core/ai_assistant/commands/paging.ts | 4 +- .../data_controller/data_controller.ts | 7 +- ...data_source_controller.integration.test.ts | 8 ++ .../__tests__/data_source_controller.test.ts | 13 +++ .../data_source/data_source_controller.ts | 6 +- .../grids/grid_core/editing/m_editing.ts | 2 +- .../m_keyboard_navigation.ts | 2 +- .../grids/grid_core/pager/m_pager.ts | 6 +- .../grids/grid_core/views/m_rows_view.ts | 2 +- .../virtual_scrolling_data_controller.ts | 9 +- .../testing/helpers/gridBaseMocks.js | 7 +- .../dataController.tests.js | 97 ++++++++++--------- .../dataGrid.tests.js | 4 +- .../pagerView.tests.js | 14 +-- .../rowsView.tests.js | 4 +- .../virtualScrolling.integration.tests.js | 2 +- 16 files changed, 109 insertions(+), 78 deletions(-) diff --git a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/commands/paging.ts b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/commands/paging.ts index d5a31a1df4d5..395fde83ec86 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/commands/paging.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/commands/paging.ts @@ -64,10 +64,10 @@ export const pageIndexCommand = defineGridCommand({ schema: pageIndexCommandSchema, execute: (component, { success, failure }) => async (args): Promise => { const paging = component.option('paging'); - const dataController = component.getController('data'); + const dataSourceController = component.getController('dataSource'); const defaultMessage = `Switch the view to page number ${args.pageIndex + 1}.`; - const isIndexValid = args.pageIndex < dataController.pageCount(); + const isIndexValid = args.pageIndex < dataSourceController.pageCount(); if (paging?.enabled === false || !isIndexValid) { return failure(defaultMessage); 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 7b3b4a23d312..ecbb7645b2f2 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 @@ -204,7 +204,6 @@ export class DataController extends modules.Controller { 'getKeyByRowIndex', 'getRowIndexByKey', 'getVisibleRows', - 'pageCount', 'pageIndex', 'pageSize', 'refresh', @@ -1341,10 +1340,6 @@ export class DataController extends modules.Controller { return !this.items().length; } - public pageCount(): number { - return this._dataSource ? this._dataSource.pageCount() : 1; - } - public loadAllItems( data?: RawItemData[], skipFilter = false, @@ -1611,7 +1606,7 @@ export class DataController extends modules.Controller { */ public isLastPageLoaded(): boolean { const pageIndex = this.pageIndex(); - const pageCount = this.pageCount(); + const pageCount = this.dataSourceController.pageCount(); return pageIndex === (pageCount - 1); } diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.integration.test.ts b/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.integration.test.ts index 3a31f250a03f..a90d6dafe66c 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.integration.test.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.integration.test.ts @@ -65,6 +65,14 @@ describe('dataSource module registration', () => { .toBe(instance.getController('dataSource').totalCount()); }); + it('owns the pageCount widget method', async () => { + const { instance } = await createDataGrid({ dataSource: DATA, paging: { pageSize: 1 } }); + + expect(instance.pageCount()).toBe(DATA.length); + expect(instance.pageCount()) + .toBe(instance.getController('dataSource').pageCount()); + }); + it('sits at the bottom of the controller order', async () => { const { instance } = await createDataGrid({ dataSource: DATA }); diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts b/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts index 09632b74d726..d969598704b6 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_source/__tests__/data_source_controller.test.ts @@ -25,6 +25,7 @@ interface AdapterStub { hasKnownLastPage: jest.Mock<() => boolean>; totalItemsCount: jest.Mock<() => number>; totalCount: jest.Mock<() => number>; + pageCount: jest.Mock<() => number>; dispose: jest.Mock<(isShared?: boolean) => void>; init: jest.Mock<(dataSource: DataSource) => void>; } @@ -44,6 +45,7 @@ const createAdapterStub = (marker: string): AdapterStub => ({ hasKnownLastPage: jest.fn(() => false), totalItemsCount: jest.fn(() => 42), totalCount: jest.fn(() => 99), + pageCount: jest.fn(() => 7), dispose: jest.fn(), init: jest.fn(), }); @@ -179,6 +181,10 @@ describe('DataSourceController', () => { expect(createController().totalCount()).toBe(0); }); + it('reports a single page', () => { + expect(createController().pageCount()).toBe(1); + }); + it('returns an empty object from remoteOperations, so callers can enumerate it', () => { const controller = createController(); @@ -245,6 +251,13 @@ describe('DataSourceController', () => { expect(adapter.totalCount).toHaveBeenCalledTimes(1); }); + it('delegates pageCount to the adapter', () => { + const { controller, adapter } = withAdapter(); + + expect(controller.pageCount()).toBe(7); + expect(adapter.pageCount).toHaveBeenCalledTimes(1); + }); + it('returns the inner DataSource from getDataSource, not the adapter', () => { const { controller, adapter } = withAdapter(); diff --git a/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts index 7f7cf610ab26..37fdd6849b00 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/data_source/data_source_controller.ts @@ -28,7 +28,7 @@ export class DataSourceController< } public publicMethods(): string[] { - return ['getDataSource', 'keyOf', 'totalCount']; + return ['getDataSource', 'keyOf', 'pageCount', 'totalCount']; } /** @@ -159,4 +159,8 @@ export class DataSourceController< public totalCount(): number { return this.adapter ? this.adapter.totalCount() : 0; } + + public pageCount(): number { + return this.adapter ? this.adapter.pageCount() : 1; + } } 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 9d25d2a22197..ec01a3a4b8cc 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 @@ -991,7 +991,7 @@ class EditingControllerImpl extends modules.ViewController { const newRowPosition: any = this._getNewRowPosition(); const dataController = this._dataController; const pageIndex = dataController.pageIndex(); - const lastPageIndex = dataController.pageCount() - 1; + const lastPageIndex = this.dataSourceController.pageCount() - 1; if (newRowPosition === FIRST_NEW_ROW_POSITION && pageIndex !== 0) { return 0; 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 85683103b999..c148ee88bd9b 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 @@ -737,7 +737,7 @@ export class KeyboardNavigationController extends KeyboardNavigationControllerCo private _pageUpDownKeyHandler(eventArgs) { const pageIndex = this._dataController.pageIndex(); - const pageCount = this._dataController.pageCount(); + const pageCount = this.dataSourceController.pageCount(); const pagingEnabled = this.option('paging.enabled'); const isPageUp = eventArgs.keyName === 'pageUp'; const pageStep = isPageUp ? -1 : 1; diff --git a/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts b/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts index 5929f9e6cd31..729e3b8e06ba 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/pager/m_pager.ts @@ -34,7 +34,7 @@ export class PagerView extends modules.View { pager.option({ pageIndex: getPageIndex(dataController), pageSize: dataController.pageSize(), - pageCount: dataController.pageCount(), + pageCount: this.dataSourceController.pageCount(), itemCount: this.dataSourceController.totalCount(), hasKnownLastPage: this.dataSourceController.hasKnownLastPage(), }); @@ -91,7 +91,7 @@ export class PagerView extends modules.View { const options: any = { maxPagesCount: MAX_PAGES_COUNT, pageIndex: getPageIndex(dataController), - pageCount: dataController.pageCount(), + pageCount: that.dataSourceController.pageCount(), pageSize: dataController.pageSize(), showPageSizeSelector: pagerOptions.showPageSizeSelector, showInfo: pagerOptions.showInfo, @@ -169,7 +169,7 @@ export class PagerView extends modules.View { if (scrolling && (scrolling.mode === 'virtual' || scrolling.mode === 'infinite')) { pagerVisible = false; } else { - pagerVisible = dataController.pageCount() > 1 + pagerVisible = this.dataSourceController.pageCount() > 1 || (dataController.isLoaded() && !this.dataSourceController.hasKnownLastPage()); } } diff --git a/packages/devextreme/js/__internal/grids/grid_core/views/m_rows_view.ts b/packages/devextreme/js/__internal/grids/grid_core/views/m_rows_view.ts index 9a27028aaa2e..170e407b2f3f 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/views/m_rows_view.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/views/m_rows_view.ts @@ -1012,7 +1012,7 @@ export class RowsView extends ColumnsView { const freeSpaceRowCount = dataController.pageSize() - itemCount; const scrollingMode = this.option('scrolling.mode'); - if (freeSpaceRowCount > 0 && dataController.pageCount() > 1 && scrollingMode !== 'virtual' && scrollingMode !== 'infinite') { + if (freeSpaceRowCount > 0 && this.dataSourceController.pageCount() > 1 && scrollingMode !== 'virtual' && scrollingMode !== 'infinite') { setHeight(freeSpaceRowElements, freeSpaceRowCount * this._rowHeight); isFreeSpaceRowVisible = true; } diff --git a/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/extenders/virtual_scrolling_data_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/extenders/virtual_scrolling_data_controller.ts index 859bd19ade8d..7e6a6d5cec96 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/extenders/virtual_scrolling_data_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/virtual_scrolling/extenders/virtual_scrolling_data_controller.ts @@ -152,7 +152,9 @@ export const virtualScrollingDataControllerExtender = ( return; } - const pageIndex = !isVirtualMode(this) && this.pageIndex() >= this.pageCount() ? this.pageCount() - 1 : this.pageIndex(); + const pageIndex = !isVirtualMode(this) && this.pageIndex() >= this.dataSourceController.pageCount() + ? this.dataSourceController.pageCount() - 1 + : this.pageIndex(); this._rowPageIndex = Math.ceil(pageIndex * this.pageSize() / this.getRowPageSize()); this._visibleItems = this.option(LEGACY_SCROLLING_MODE) === false ? null : []; this._viewportChanging = false; @@ -764,7 +766,8 @@ export const virtualScrollingDataControllerExtender = ( } private handlePagesLoaded(viewportChanging: boolean): void { - const isLastPage = this.pageCount() > 0 && this.pageIndex() === this.pageCount() - 1; + const isLastPage = this.dataSourceController.pageCount() > 0 + && this.pageIndex() === this.dataSourceController.pageCount() - 1; if (viewportChanging || isLastPage) { this._updateVisiblePageIndex(); @@ -942,7 +945,7 @@ export const virtualScrollingDataControllerExtender = ( if (this.option(LEGACY_SCROLLING_MODE) === false && isVirtualPaging(this)) { const { pageIndex, loadPageCount } = this.getLoadPageParams(true); - const pageCount = this.pageCount(); + const pageCount = this.dataSourceController.pageCount(); result = pageIndex + loadPageCount >= pageCount; } else { diff --git a/packages/devextreme/testing/helpers/gridBaseMocks.js b/packages/devextreme/testing/helpers/gridBaseMocks.js index 8b089d748c03..8d2bb26758db 100644 --- a/packages/devextreme/testing/helpers/gridBaseMocks.js +++ b/packages/devextreme/testing/helpers/gridBaseMocks.js @@ -64,6 +64,9 @@ module.exports = function($, gridCore, columnResizingReordering, domUtils, commo totalCount: function() { return options.totalCount || 0; }, + pageCount: function() { + return options.pageCount; + }, dispose: function() { }, store: function() { @@ -141,10 +144,6 @@ module.exports = function($, gridCore, columnResizingReordering, domUtils, commo this.changed.fire(); }, - pageCount: function() { - return options.pageCount; - }, - pageIndex: function(index) { if(typeUtils.isDefined(index)) { options.pageIndex = index; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js index 66a5c92e826f..01b6561aa238 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js @@ -1209,7 +1209,7 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod // act this.dataController.resetDataSource(); - assert.equal(this.dataController.pageCount(), 2); + assert.equal(this.dataSourceController.pageCount(), 2); this.dataController.getPageIndexByKey('Bob').done(function(pageIndex) { assert.equal(pageIndex, 1); }); @@ -1234,7 +1234,7 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod // act this.dataController.resetDataSource(); - assert.equal(this.dataController.pageCount(), 4); + assert.equal(this.dataSourceController.pageCount(), 4); this.dataController.getPageIndexByKey('Bob').done(function(pageIndex) { assert.equal(pageIndex, 3); }); @@ -1261,10 +1261,11 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod // act const dataController = this.dataController; + const dataSourceController = this.dataSourceController; dataController.resetDataSource(); // assert dataController.getPageIndexByKey({ name: 'Bob', age: 24 }).done(function(pageIndex) { - assert.equal(dataController.pageCount(), 5); + assert.equal(dataSourceController.pageCount(), 5); assert.equal(pageIndex, 3); }); }); @@ -1292,11 +1293,12 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod // act const dataController = this.dataController; + const dataSourceController = this.dataSourceController; dataController.resetDataSource(); // assert dataController.getGlobalRowIndexByKey('Mark').done(function(globalRowIndex) { ++foundRowCount; - assert.equal(dataController.pageCount(), 4, 'Page count'); + assert.equal(dataSourceController.pageCount(), 4, 'Page count'); assert.equal(globalRowIndex, 5, 'Mark'); }); dataController.getGlobalRowIndexByKey('Alex').done(function(globalRowIndex) { @@ -1376,11 +1378,12 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod // act const dataController = this.dataController; + const dataSourceController = this.dataSourceController; dataController.resetDataSource(); // assert dataController.getGlobalRowIndexByKey(1).done(globalRowIndex => { - assert.equal(dataController.pageCount(), 3, 'Page count'); + assert.equal(dataSourceController.pageCount(), 3, 'Page count'); assert.equal(globalRowIndex, 1, 'globalRowIndex'); done(); }); @@ -1412,11 +1415,12 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod // act const dataController = this.dataController; + const dataSourceController = this.dataSourceController; dataController.resetDataSource(); // assert dataController.getGlobalRowIndexByKey('Sad').done(function(globalRowIndex) { ++foundRowCount; - assert.equal(dataController.pageCount(), 5, 'Page count'); + assert.equal(dataSourceController.pageCount(), 5, 'Page count'); assert.equal(globalRowIndex, 4, 'Sad'); }); dataController.getGlobalRowIndexByKey('Alex').done(function(globalRowIndex) { @@ -1480,11 +1484,12 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod // act const dataController = this.dataController; + const dataSourceController = this.dataSourceController; dataController.resetDataSource(); // assert dataController.getGlobalRowIndexByKey('Sad').done(function(globalRowIndex) { ++foundRowCount; - assert.equal(dataController.pageCount(), 5, 'Page count'); + assert.equal(dataSourceController.pageCount(), 5, 'Page count'); assert.equal(globalRowIndex, 4, 'Sad'); }); dataController.getGlobalRowIndexByKey('Alex').done(function(globalRowIndex) { @@ -1548,11 +1553,12 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod // act const dataController = this.dataController; + const dataSourceController = this.dataSourceController; dataController.resetDataSource(); // assert dataController.getGlobalRowIndexByKey('Sad').done(function(globalRowIndex) { ++foundRowCount; - assert.equal(dataController.pageCount(), 3, 'Page count'); + assert.equal(dataSourceController.pageCount(), 3, 'Page count'); assert.equal(globalRowIndex, 2, 'Sad'); }); dataController.getGlobalRowIndexByKey('Alex').done(function(globalRowIndex) { @@ -1615,11 +1621,12 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod // act const dataController = this.dataController; + const dataSourceController = this.dataSourceController; dataController.resetDataSource(); // assert dataController.getGlobalRowIndexByKey('Alex').done(function(globalRowIndex) { ++foundRowCount; - assert.equal(dataController.pageCount(), 5, 'Page count'); + assert.equal(dataSourceController.pageCount(), 5, 'Page count'); assert.equal(globalRowIndex, 2, 'Alex'); }); dataController.getGlobalRowIndexByKey('Bob').done(function(globalRowIndex) { @@ -1683,11 +1690,12 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod // act const dataController = this.dataController; + const dataSourceController = this.dataSourceController; dataController.resetDataSource(); // assert dataController.getGlobalRowIndexByKey('Alex').done(function(globalRowIndex) { ++foundRowCount; - assert.equal(dataController.pageCount(), 5, 'Page count'); + assert.equal(dataSourceController.pageCount(), 5, 'Page count'); assert.equal(globalRowIndex, 2, 'Alex'); }); dataController.getGlobalRowIndexByKey('Bob').done(function(globalRowIndex) { @@ -1755,11 +1763,12 @@ QUnit.module('Initialization', { beforeEach: setupModule, afterEach: teardownMod // act const dataController = this.dataController; + const dataSourceController = this.dataSourceController; dataController.resetDataSource(); // assert dataController.getGlobalRowIndexByKey('Alex').done(function(globalRowIndex) { ++foundRowCount; - assert.equal(dataController.pageCount(), 2, 'Page count'); + assert.equal(dataSourceController.pageCount(), 2, 'Page count'); assert.equal(globalRowIndex, 0, 'Alex'); }); dataController.getGlobalRowIndexByKey('Bob').done(function(globalRowIndex) { @@ -2849,7 +2858,7 @@ QUnit.module('No dataSource', { beforeEach: setupModule, afterEach: teardownModu QUnit.test('getters', function(assert) { assert.strictEqual(this.dataController.items().length, 0); assert.strictEqual(this.dataSourceController.totalItemsCount(), 0); - assert.strictEqual(this.dataController.pageCount(), 1); + assert.strictEqual(this.dataSourceController.pageCount(), 1); assert.strictEqual(this.dataController.pageIndex(), 0); assert.strictEqual(this.dataController.pageSize(), 0); assert.strictEqual(this.dataController.isLoading(), false); @@ -3075,7 +3084,7 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin assert.equal(this.dataController.items().length, 5); assert.equal(this.dataSourceController.totalCount(), 7); - assert.equal(this.dataController.pageCount(), 2); + assert.equal(this.dataSourceController.pageCount(), 2); assert.equal(this.dataController.pageIndex(), 0); assert.ok(this.dataSourceController.hasKnownLastPage()); assert.deepEqual(this.dataController.items()[0].values, ['Alex', 215]); @@ -3099,7 +3108,7 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin assert.equal(changedCount, 1); assert.equal(this.dataController.items().length, 1); assert.equal(this.dataSourceController.totalCount(), 1); - assert.equal(this.dataController.pageCount(), 1); + assert.equal(this.dataSourceController.pageCount(), 1); assert.equal(this.dataController.pageIndex(), 0); assert.deepEqual(this.dataController.items()[0].values, ['Dan3', 153]); }); @@ -3188,7 +3197,7 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin // assert assert.equal(this.dataController.items().length, 3); - assert.equal(this.dataController.pageCount(), 3); + assert.equal(this.dataSourceController.pageCount(), 3); assert.equal(this.dataController.pageIndex(), 1); assert.deepEqual(this.dataController.items()[0].values, ['Dan3', 153]); @@ -3207,14 +3216,14 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin // assert assert.equal(this.dataController.pageSize(), 2); - assert.equal(this.dataController.pageCount(), 4); + assert.equal(this.dataSourceController.pageCount(), 4); // act this.dataController.optionChanged({ name: 'dataSource' }); // assert assert.equal(this.dataController.pageSize(), 2); - assert.equal(this.dataController.pageCount(), 4); + assert.equal(this.dataSourceController.pageCount(), 4); assert.equal(this.option('paging.pageSize'), 2); }); @@ -3230,14 +3239,14 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin // assert assert.equal(this.dataController.pageIndex(), 1); - assert.equal(this.dataController.pageCount(), 2); + assert.equal(this.dataSourceController.pageCount(), 2); // act this.dataController.optionChanged({ name: 'dataSource' }); // assert assert.equal(this.dataController.pageIndex(), 1); - assert.equal(this.dataController.pageCount(), 2); + assert.equal(this.dataSourceController.pageCount(), 2); assert.equal(this.option('paging.pageIndex'), 1); }); @@ -3320,7 +3329,7 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin assert.equal(this.dataController.pageIndex(), 0); assert.equal(this.dataSourceController.totalCount(), 11); - assert.equal(this.dataController.pageCount(), 3); + assert.equal(this.dataSourceController.pageCount(), 3); assert.equal(changedCount, 1, 'changed raise after reload'); }); @@ -3336,7 +3345,7 @@ QUnit.module('Paging', { beforeEach: setupPagingModule, afterEach: teardownPagin this.dataController.resetDataSource(); assert.equal(this.dataController.pageIndex(), 1); - assert.equal(this.dataController.pageCount(), 3); + assert.equal(this.dataSourceController.pageCount(), 3); assert.ok(this.dataSourceController.hasKnownLastPage()); assert.equal(this.dataSourceController.totalCount(), 7); assert.equal(this.dataController.items().length, 3); @@ -4087,7 +4096,7 @@ QUnit.module('Virtual rendering', { beforeEach: setupVirtualRenderingModule, aft // assert assert.strictEqual(this.dataController.items().length, 0, 'item count'); - assert.strictEqual(this.dataController.pageCount(), 1, 'page count'); + assert.strictEqual(this.dataSourceController.pageCount(), 1, 'page count'); // act this.option('searchPanel.text', ''); @@ -4095,7 +4104,7 @@ QUnit.module('Virtual rendering', { beforeEach: setupVirtualRenderingModule, aft // assert assert.strictEqual(this.dataController.items().length, 10, 'item count'); - assert.strictEqual(this.dataController.pageCount(), 5, 'page count'); + assert.strictEqual(this.dataSourceController.pageCount(), 5, 'page count'); }); QUnit.test('addRow > scroll to far > scroll back', function(assert) { @@ -9335,7 +9344,7 @@ QUnit.module('Remote Grouping', { assert.deepEqual(storeLoadOptions.group, [{ selector: 'name', desc: false, isExpanded: false }], 'group option'); assert.equal(this.dataSourceController.totalCount(), -1, 'totalCount'); - assert.equal(this.dataController.pageCount(), 1, 'pageCount'); + assert.equal(this.dataSourceController.pageCount(), 1, 'pageCount'); }); // T366766 @@ -9380,7 +9389,7 @@ QUnit.module('Remote Grouping', { assert.deepEqual(storeLoadOptions.group, [{ selector: 'name', desc: false, isExpanded: false }], 'group option'); assert.equal(this.dataSourceController.totalCount(), -1, 'totalCount'); - assert.equal(this.dataController.pageCount(), 1, 'pageCount'); + assert.equal(this.dataSourceController.pageCount(), 1, 'pageCount'); }); // T317797 @@ -9422,7 +9431,7 @@ QUnit.module('Remote Grouping', { assert.equal(this.dataSourceController.totalCount(), 10, 'totalCount'); assert.equal(this.dataSourceController.hasKnownLastPage(), true, 'hasKnownLastPage'); assert.equal(this.dataController.items().length, 2, 'items count'); - assert.equal(this.dataController.pageCount(), 5, 'pageCount'); + assert.equal(this.dataSourceController.pageCount(), 5, 'pageCount'); }); // T318309 @@ -9450,7 +9459,7 @@ QUnit.module('Remote Grouping', { // assert assert.equal(this.dataSourceController.totalCount(), 2, 'totalCount'); - assert.equal(this.dataController.pageCount(), 1, 'pageCount'); + assert.equal(this.dataSourceController.pageCount(), 1, 'pageCount'); assert.deepEqual(this.dataController.items()[0].rowType, 'group', 'item 1 rowType'); assert.deepEqual(this.dataController.items()[0].key, ['1980/10/15'], 'item 1 key'); assert.deepEqual(this.dataController.items()[0].values, [new Date('1980/10/15')], 'item 1 values'); @@ -9846,7 +9855,7 @@ QUnit.module('Summary', { assert.deepEqual(storeLoadOptions.groupSummary, undefined, 'summary groupItems option'); assert.ok(!this.dataController.isLoading()); assert.equal(this.dataSourceController.totalCount(), 4, 'totalCount'); - assert.equal(this.dataController.pageCount(), 4, 'pageCount'); + assert.equal(this.dataSourceController.pageCount(), 4, 'pageCount'); assert.deepEqual(this.dataController.items().length, 2); assert.deepEqual(this.dataController.items()[0].data, { key: 'Alex', @@ -9919,7 +9928,7 @@ QUnit.module('Summary', { assert.deepEqual(storeLoadOptions.groupSummary, undefined, 'summary groupItems option'); assert.ok(!this.dataController.isLoading()); assert.equal(this.dataSourceController.totalCount(), 4, 'totalCount'); - assert.equal(this.dataController.pageCount(), 4, 'pageCount'); + assert.equal(this.dataSourceController.pageCount(), 4, 'pageCount'); assert.deepEqual(this.dataController.items().length, 2); assert.deepEqual(this.dataController.items()[0].data, { key: 'Alex', @@ -9987,7 +9996,7 @@ QUnit.module('Summary', { assert.deepEqual(storeLoadOptions.groupSummary, undefined, 'summary groupItems option'); assert.ok(!this.dataController.isLoading()); assert.equal(this.dataSourceController.totalCount(), 10, 'totalCount'); - assert.equal(this.dataController.pageCount(), 5, 'pageCount'); + assert.equal(this.dataSourceController.pageCount(), 5, 'pageCount'); assert.deepEqual(this.dataController.items().length, 3); assert.deepEqual(this.dataController.items()[0].data, { key: 'Alex', @@ -10108,7 +10117,7 @@ QUnit.module('Summary', { assert.deepEqual(storeLoadOptions.groupSummary, [{ selector: 'age', summaryType: 'count' }], 'summary groupItems option'); assert.ok(!this.dataController.isLoading()); assert.equal(this.dataSourceController.totalCount(), 2, 'totalCount'); - assert.equal(this.dataController.pageCount(), 1, 'pageCount'); + assert.equal(this.dataSourceController.pageCount(), 1, 'pageCount'); assert.deepEqual(this.dataController.items()[0].summaryCells, [[], [{ column: 'age', columnCaption: 'Age', @@ -10173,7 +10182,7 @@ QUnit.module('Summary', { assert.deepEqual(storeLoadOptions.groupSummary, [{ selector: 'age', summaryType: 'count' }], 'summary groupItems option'); assert.ok(!this.dataController.isLoading()); assert.equal(this.dataSourceController.totalCount(), 2, 'totalCount'); - assert.equal(this.dataController.pageCount(), 1, 'pageCount'); + assert.equal(this.dataSourceController.pageCount(), 1, 'pageCount'); assert.deepEqual(this.dataController.items()[0].summaryCells, [[], [{ column: 'age', columnCaption: 'Age', @@ -10242,7 +10251,7 @@ QUnit.module('Summary', { assert.deepEqual(storeLoadOptions.filter, [['group', '=', 'Group1'], 'or', ['group', '=', 'Group0']], 'filter option'); assert.deepEqual(storeLoadOptions.sort, [{ 'desc': false, 'isExpanded': true, 'selector': 'group' }], 'sort option'); assert.equal(this.dataSourceController.totalCount(), 3, 'totalCount'); - assert.equal(this.dataController.pageCount(), 2, 'pageCount'); + assert.equal(this.dataSourceController.pageCount(), 2, 'pageCount'); const items = this.dataController.items(); assert.equal(items.length, 4, 'item count'); assert.deepEqual(items[0].key, ['Group1'], 'item 0'); @@ -10368,7 +10377,7 @@ QUnit.module('Summary', { assert.deepEqual(storeLoadOptions.sort, [{ 'desc': false, 'isExpanded': true, 'selector': 'group1' }, { 'desc': false, 'isExpanded': true, 'selector': 'group2' }], 'sort option'); assert.equal(this.dataSourceController.totalCount(), 3, 'totalCount'); - assert.equal(this.dataController.pageCount(), 2, 'pageCount'); + assert.equal(this.dataSourceController.pageCount(), 2, 'pageCount'); const items = this.dataController.items(); assert.equal(items.length, 6, 'item count'); assert.deepEqual(items[0].key, ['Group1'], 'item 0'); @@ -14442,7 +14451,7 @@ QUnit.module('Using DataSource instance', { // assert assert.equal(this.dataController.items().length, 3, 'items count'); assert.equal(this.dataSourceController.totalCount(), 5, 'total count'); - assert.equal(this.dataController.pageCount(), 2, 'page count'); + assert.equal(this.dataSourceController.pageCount(), 2, 'page count'); }); // T752955 @@ -14583,7 +14592,7 @@ QUnit.module('Exporting', { // assert assert.deepEqual(this.dataController.items().length, 3, 'items count'); assert.deepEqual(this.dataController.pageSize(), 3, 'pageSize'); - assert.deepEqual(this.dataController.pageCount(), 2, 'pageCount'); + assert.deepEqual(this.dataSourceController.pageCount(), 2, 'pageCount'); assert.deepEqual(changedCallCount, 0, 'changed call count'); @@ -14631,7 +14640,7 @@ QUnit.module('Exporting', { // assert assert.deepEqual(this.dataController.items().length, 2, 'items count'); assert.deepEqual(this.dataController.pageSize(), 3, 'pageSize'); - assert.deepEqual(this.dataController.pageCount(), 1, 'pageCount'); + assert.deepEqual(this.dataSourceController.pageCount(), 1, 'pageCount'); assert.deepEqual(changedCallCount, 0, 'changed call count'); @@ -14670,7 +14679,7 @@ QUnit.module('Exporting', { this.clock.tick(10); - assert.deepEqual(this.dataController.pageCount(), 4, 'pageCount'); + assert.deepEqual(this.dataSourceController.pageCount(), 4, 'pageCount'); this.dataController.changed.add(function() { @@ -14688,7 +14697,7 @@ QUnit.module('Exporting', { assert.deepEqual(this.dataController.items().length, 4, 'items count'); assert.deepEqual(this.dataController.pageSize(), 3, 'pageSize'); // T240474 - assert.deepEqual(this.dataController.pageCount(), 4, 'pageCount'); + assert.deepEqual(this.dataSourceController.pageCount(), 4, 'pageCount'); assert.deepEqual(changedCallCount, 0, 'changed call count'); @@ -14742,7 +14751,7 @@ QUnit.module('Exporting', { this.clock.tick(10); - assert.deepEqual(this.dataController.pageCount(), 1, 'pageCount'); + assert.deepEqual(this.dataSourceController.pageCount(), 1, 'pageCount'); this.dataController.changed.add(function() { @@ -14821,7 +14830,7 @@ QUnit.module('Exporting', { this.clock.tick(10); - assert.deepEqual(this.dataController.pageCount(), 1, 'pageCount'); + assert.deepEqual(this.dataSourceController.pageCount(), 1, 'pageCount'); this.dataController.changed.add(function() { @@ -14911,7 +14920,7 @@ QUnit.module('Exporting', { this.clock.tick(10); - assert.deepEqual(this.dataController.pageCount(), 1, 'pageCount'); + assert.deepEqual(this.dataSourceController.pageCount(), 1, 'pageCount'); this.dataController.changed.add(function() { @@ -15201,7 +15210,7 @@ QUnit.module('Exporting', { // assert assert.deepEqual(this.dataController.items().length, 3, 'items count'); assert.deepEqual(this.dataController.pageSize(), 3, 'pageSize'); - assert.deepEqual(this.dataController.pageCount(), 2, 'pageCount'); + assert.deepEqual(this.dataSourceController.pageCount(), 2, 'pageCount'); assert.deepEqual(changedCallCount, 0, 'changed call count'); @@ -15250,7 +15259,7 @@ QUnit.module('Exporting', { // assert assert.deepEqual(this.dataController.items().length, 2, 'items count'); assert.deepEqual(this.dataController.pageSize(), 3, 'pageSize'); - assert.deepEqual(this.dataController.pageCount(), 1, 'pageCount'); + assert.deepEqual(this.dataSourceController.pageCount(), 1, 'pageCount'); assert.deepEqual(changedCallCount, 0, 'changed call count'); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataGrid.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataGrid.tests.js index 074b5e6b1d11..56755d970cf8 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataGrid.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataGrid.tests.js @@ -1963,7 +1963,7 @@ QUnit.module('Assign options', baseModuleConfig, () => { }); dataGrid.selectRows({ a: 1111, b: 222 }); - assert.deepEqual(dataGrid.getController('data').pageCount(), 2, 'pages count'); + assert.deepEqual(dataGrid.getController('dataSource').pageCount(), 2, 'pages count'); assert.deepEqual(dataGrid.getController('data').items().length, 3, 'items count'); assert.ok(dataGrid.getView('pagerView').isVisible(), 'pager visibility'); @@ -1971,7 +1971,7 @@ QUnit.module('Assign options', baseModuleConfig, () => { dataGrid.option('paging.enabled', false); // assert - assert.deepEqual(dataGrid.getController('data').pageCount(), 1, 'pages count when paging disabled'); + assert.deepEqual(dataGrid.getController('dataSource').pageCount(), 1, 'pages count when paging disabled'); assert.deepEqual(dataGrid.getController('data').items().length, 5, 'items count when paging disabled'); assert.ok(!dataGrid.getView('pagerView').isVisible(), 'pager visibility when paging disabled'); }); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/pagerView.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/pagerView.tests.js index 3220bd37480a..30dd86c9ac15 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/pagerView.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/pagerView.tests.js @@ -411,7 +411,7 @@ QUnit.module('Pager', { const isVisible = pagerView.isVisible(); // assert - assert.equal(this.dataController.pageCount(), 2); + assert.equal(this.dataSourceController.pageCount(), 2); assert.ok(isVisible); assert.equal(pagerView.element().dxPagination('instance').option('pagesNavigatorVisible'), 'auto', 'pagesNavigatorVisible'); }); @@ -426,7 +426,7 @@ QUnit.module('Pager', { const isVisible = pagerView.isVisible(); // assert - assert.equal(this.dataController.pageCount(), 1); + assert.equal(this.dataSourceController.pageCount(), 1); assert.ok(!isVisible); }); @@ -444,7 +444,7 @@ QUnit.module('Pager', { // assert assert.ok(!this.dataSourceController.hasKnownLastPage()); - assert.equal(this.dataController.pageCount(), 1); + assert.equal(this.dataSourceController.pageCount(), 1); assert.ok(isVisible); }); @@ -459,7 +459,7 @@ QUnit.module('Pager', { const isVisible = pagerView.isVisible(); // assert - assert.equal(this.dataController.pageCount(), 1); + assert.equal(this.dataSourceController.pageCount(), 1); assert.ok(isVisible); assert.equal(pagerView.element().dxPagination('instance').option('pagesNavigatorVisible'), true, 'pagesNavigatorVisible'); }); @@ -476,7 +476,7 @@ QUnit.module('Pager', { const isVisible = pagerView.isVisible(); // assert - assert.equal(this.dataController.pageCount(), 2); + assert.equal(this.dataSourceController.pageCount(), 2); assert.ok(!isVisible); assert.equal(dataUtils.data(pagerView.element().get(0), 'dxPager'), undefined, 'pager instance'); }); @@ -494,7 +494,7 @@ QUnit.module('Pager', { const isVisible = pagerView.isVisible(); // assert - assert.equal(this.dataController.pageCount(), 1); + assert.equal(this.dataSourceController.pageCount(), 1); assert.ok(!isVisible); }); @@ -511,7 +511,7 @@ QUnit.module('Pager', { const isVisible = pagerView.isVisible(); // assert - assert.equal(this.dataController.pageCount(), 1); + assert.equal(this.dataSourceController.pageCount(), 1); assert.deepEqual(this.dataController.getPageSizes(), []); assert.ok(!isVisible); }); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/rowsView.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/rowsView.tests.js index 232f18a9723c..07cf8ca0d518 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/rowsView.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/rowsView.tests.js @@ -4653,7 +4653,7 @@ QUnit.module('Rows view with real dataController and columnController', { that.rowsView.resize(); // assert - assert.equal(that.dataController.pageCount(), 3, 'page count = 3'); + assert.equal(that.dataSourceController.pageCount(), 3, 'page count = 3'); assert.ok(!that.rowsView._hasHeight, 'not has height'); assert.ok(that.rowsView._rowHeight > 0, 'row height > 0'); assert.equal(Math.round(getHeight(that.rowsView._getFreeSpaceRowElements())), Math.round(that.rowsView._rowHeight * 2), 'height free space row'); @@ -4679,7 +4679,7 @@ QUnit.module('Rows view with real dataController and columnController', { that.rowsView.resize(); // assert - assert.equal(that.dataController.pageCount(), 3, 'page count = 3'); + assert.equal(that.dataSourceController.pageCount(), 3, 'page count = 3'); assert.ok(!that.rowsView._hasHeight, 'not has height'); assert.ok(that.rowsView._rowHeight > 0, 'row height > 0'); assert.equal(getHeight(that.rowsView._getFreeSpaceRowElements()), 0, 'no height free space row'); diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/virtualScrolling.integration.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/virtualScrolling.integration.tests.js index fcf55d210597..9f2bb020d851 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/virtualScrolling.integration.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/virtualScrolling.integration.tests.js @@ -3242,7 +3242,7 @@ QUnit.module('Virtual Scrolling', baseModuleConfig, () => { this.clock.tick(10); // assert - assert.deepEqual(dataGrid.getController('data').pageCount(), 2, 'pages count'); + assert.deepEqual(dataGrid.getController('dataSource').pageCount(), 2, 'pages count'); assert.deepEqual(dataGrid.getController('data').items().length, 5, 'items count'); assert.ok(!dataGrid.getView('pagerView').isVisible(), 'pager visibility'); }); From 11d22bc63154e9a5964be2e02be04a132f05b388 Mon Sep 17 00:00:00 2001 From: "anna.shakhova" <68295572+anna-shakhova@users.noreply.github.com> Date: Wed, 9 Sep 2026 17:00:15 +0200 Subject: [PATCH 5/5] Grids: remove unused in production code `itemsCount` method --- .../grid_core/data_controller/data_controller.ts | 4 ---- .../columnsResizingReorderingModule.tests.js | 4 +++- .../dataController.tests.js | 14 +++++++------- 3 files changed, 10 insertions(+), 12 deletions(-) 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 ecbb7645b2f2..9c52668a6adc 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 @@ -1626,10 +1626,6 @@ export class DataController extends modules.Controller { this._dataSource?.push(changes, fromStore); } - private itemsCount(): number { - return (this._dataSource ? this._dataSource.itemsCount() : 0); - } - /** * @extended: state_storing */ diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/columnsResizingReorderingModule.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/columnsResizingReorderingModule.tests.js index 545a24d13539..045056dce0f9 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/columnsResizingReorderingModule.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/columnsResizingReorderingModule.tests.js @@ -970,7 +970,9 @@ QUnit.module('Columns resizing', { dataSource: { key: noop, - store: noop + store: noop, + pageCount: () => 1, + totalCount: () => 0 }, columnsResizer: { diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js index 01b6561aa238..b88e5d1f213a 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/dataController.tests.js @@ -3979,7 +3979,7 @@ QUnit.module('Virtual rendering', { beforeEach: setupVirtualRenderingModule, aft assert.deepEqual(this.dataController.items()[itemCount - 2].key, ['value99']); assert.strictEqual(this.dataController.items()[itemCount - 1].key, 99); assert.strictEqual(this.dataController.pageIndex(), 0); - assert.strictEqual(this.dataController.itemsCount(), 100); + assert.strictEqual(this.dataSourceController.getAdapter().itemsCount(), 100); }); QUnit.test('scroll to previous render page', function(assert) { @@ -4687,7 +4687,7 @@ QUnit.module('Virtual scrolling (ScrollingDataSource)', { // assert assert.deepEqual(this.getDataItems(), items); - assert.equal(dataController.itemsCount(), 5); + assert.equal(this.dataSourceController.getAdapter().itemsCount(), 5); assert.ok(dataController.isLoaded()); assert.ok(!dataController.isLoading(), 'loading completed'); assert.ok(!isLoadingByEvent, 'loading completed'); @@ -4716,7 +4716,7 @@ QUnit.module('Virtual scrolling (ScrollingDataSource)', { // assert assert.deepEqual(this.getDataItems(), TEN_NUMBERS); - assert.equal(dataController.itemsCount(), 10); + assert.equal(this.dataSourceController.getAdapter().itemsCount(), 10); assert.ok(dataController.isLoaded()); assert.ok(!dataController.isLoading(), 'loading completed'); assert.ok(!isLoadingByEvent, 'loading completed'); @@ -14256,7 +14256,7 @@ QUnit.module('Using DataSource instance', { // assert assert.ok(!this.dataSource.filter(), 'no filter'); - assert.equal(this.dataController.itemsCount(), 3); + assert.equal(this.dataSourceController.getAdapter().itemsCount(), 3); assert.equal(this.dataSourceController.totalCount(), 3); // act @@ -14268,7 +14268,7 @@ QUnit.module('Using DataSource instance', { const filter = this.dataSource.filter(); assert.deepEqual(this.dataSource.filter(), [filter[0], '=', 2], 'changed filter'); assert.equal(this.dataController.items()[0].data.field3, 6); - assert.equal(this.dataController.itemsCount(), 2); + assert.equal(this.dataSourceController.getAdapter().itemsCount(), 2); assert.equal(this.dataSourceController.totalCount(), 2); }); @@ -14304,7 +14304,7 @@ QUnit.module('Using DataSource instance', { assert.strictEqual(this.columnOption(2, 'groupIndex'), undefined); assert.deepEqual(changes, ['columns', 'data']); - assert.equal(this.dataController.itemsCount(), 5); + assert.equal(this.dataSourceController.getAdapter().itemsCount(), 5); assert.equal(this.dataSourceController.totalItemsCount(), 8); assert.equal(this.dataController.items()[0].rowType, 'group'); assert.equal(this.dataController.items()[1].rowType, 'data'); @@ -14346,7 +14346,7 @@ QUnit.module('Using DataSource instance', { assert.strictEqual(this.columnOption(2, 'sortOrder'), 'desc'); assert.deepEqual(changes, ['columns', 'data']); - assert.equal(this.dataController.itemsCount(), 5); + assert.equal(this.dataSourceController.getAdapter().itemsCount(), 5); assert.equal(this.dataSourceController.totalItemsCount(), 5); assert.equal(this.dataController.items()[0].data.field3, 7); assert.equal(this.dataController.items()[4].data.field3, 3);