Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions packages/devextreme/js/__internal/data/data_source/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import type { DeferredObj } from '@js/core/utils/deferred';
import type { DataSourceOptionsStub } from '@js/data/data_source';
import type PublicDataSource from '@js/data/data_source';
import type { StoreChange } from '@js/data/store';
import type { EventsStrategy } from '@ts/core/m_events_strategy';
import type Store from '@ts/data/abstract_store';

export interface StoreLoadOptions extends Pick<
Expand Down Expand Up @@ -65,26 +63,3 @@ export type DataSourceEventName = | 'changed'
| 'customizeStoreLoadOptions'
| 'customizeLoadResult'
| 'changing';

export interface DataSource extends PublicDataSource {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have replaced usages of this temp interface by the DataSource class

_eventsStrategy: EventsStrategy;

_reshapeOnPush: boolean;

_scheduleLoadCallbacks: (deferred: DeferredObj<unknown>) => void;

_createStoreLoadOptions: () => StoreLoadOptions;

beginLoading: () => void;

endLoading: () => void;

loadOptions: () => StoreLoadOptions;

// eslint-disable-next-line @typescript-eslint/method-signature-style
on(eventName: DataSourceEventName, eventHandler: Function): this;
// eslint-disable-next-line @typescript-eslint/method-signature-style
on(events: { [key in DataSourceEventName]?: Function }): this;
// eslint-disable-next-line @typescript-eslint/method-signature-style
off(eventName: DataSourceEventName, eventHandler?: Function): this;
}
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ export class ExportController extends dataGridCore.ViewController {
let summaryCells;

when(data).done((data) => {
this._dataController.loadAll(data, skipFilter).done((sourceItems, totalAggregates) => {
this._dataController.loadAllItems(data, skipFilter).done((sourceItems, totalAggregates) => {
that._updateGroupValuesWithSummaryByColumn(sourceItems);

if (that._hasSummaryGroupFooters()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,10 @@ const data = (Base: DataControllerBase) => class FocusDataControllerExtender ext
return deferred;
}

dataSource.load({
dataSource.customLoader.load({
filter: this._concatWithCombinedFilter(filter),
group,
}).done((data) => {
// @ts-expect-error badly typed DataSourceAdapter
}).done(({ data }) => {
const hasData = isDefined(data) && data.length > 0;

if (this._dataSource !== dataSource || !hasData) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { GroupingHelper, updateGroupOffsets } from '../m_grouping_expanded';
import type { DataItem, GroupInfoData, GroupItemData } from '../types';
import { createDataSourceAdapterStub } from './m_grouping_expanded.mock';

export interface GroupConfig {
key: string;
Expand Down Expand Up @@ -35,7 +36,7 @@ export class GroupingTestHelper {
private readonly savedChildren = new Map<string, GroupItemData[] | null>();

constructor(groups: GroupConfig[]) {
this.grouping = new GroupingHelper({ option: (): undefined => undefined });
this.grouping = new GroupingHelper(createDataSourceAdapterStub());
this.groupsByKey = new Map();
this.leafCounts = new Map();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type DataSourceAdapter from '@ts/grids/grid_core/data_source_adapter/m_data_source_adapter';

import { GroupingHelper } from '../m_grouping_expanded';

export const createDataSourceAdapterStub = (): DataSourceAdapter => ({
option: (): undefined => undefined,
} as unknown as DataSourceAdapter);

/** Subclass that exposes the protected handleDataLoading method for testing. */
export class GroupingHelperMock extends GroupingHelper {
public testHandleDataLoading(options: unknown): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { describe, expect, it } from '@jest/globals';

import type { GroupConfig } from './m_grouping_expanded.helpers';
import { GroupingTestHelper } from './m_grouping_expanded.helpers';
import { GroupingHelperMock } from './m_grouping_expanded.mock';
import { createDataSourceAdapterStub, GroupingHelperMock } from './m_grouping_expanded.mock';

// ---------------------------------------------------------------------------
// Test data
Expand Down Expand Up @@ -247,7 +247,7 @@ describe('isPending logic', () => {

describe('handleDataLoading: expandCorrection', () => {
it('should widen the load window for collapsed groups after the expanding one', () => {
const grouping = new GroupingHelperMock({ option: (): undefined => undefined });
const grouping = new GroupingHelperMock(createDataSourceAdapterStub());

// Group A was just expanded — isPending + isExpanded, count=100
grouping.addGroupInfo({
Expand Down Expand Up @@ -275,7 +275,7 @@ describe('isPending logic', () => {
});

it('should NOT widen the load window for previously expanded groups (not pending)', () => {
const grouping = new GroupingHelperMock({ option: (): undefined => undefined });
const grouping = new GroupingHelperMock(createDataSourceAdapterStub());

// Group A is expanded but NOT pending (normal steady state)
grouping.addGroupInfo({
Expand All @@ -301,7 +301,7 @@ describe('isPending logic', () => {

describe('handleDataLoading: isPending cleanup', () => {
it('should delete isPending from an expanded group after processing', () => {
const grouping = new GroupingHelperMock({ option: (): undefined => undefined });
const grouping = new GroupingHelperMock(createDataSourceAdapterStub());

grouping.addGroupInfo({
offset: 0, count: 100, isExpanded: true, isPending: true, path: ['A'],
Expand All @@ -317,7 +317,7 @@ describe('isPending logic', () => {
});

it('should delete isPending from a collapsed group after processing', () => {
const grouping = new GroupingHelperMock({ option: (): undefined => undefined });
const grouping = new GroupingHelperMock(createDataSourceAdapterStub());

grouping.addGroupInfo({
offset: 0, count: 10, isExpanded: false, isPending: true, path: ['A'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Deferred, when } from '@js/core/utils/deferred';
import { extend } from '@js/core/utils/extend';
import { each } from '@js/core/utils/iterator';
import errors from '@js/ui/widget/ui.errors';
import type DataSourceAdapter from '@ts/grids/grid_core/data_source_adapter/m_data_source_adapter';
import type { RawItemData } from '@ts/grids/grid_core/data_source_adapter/types';

import dataGridCore from '../m_core';
import { createGroupFilter } from '../m_utils';
Expand Down Expand Up @@ -196,7 +198,7 @@ function makeDataDeferred(options) {
}
}

function loadGroupItems(that, options, loadedGroupCount, expandedInfo, groupLevel, data) {
function loadGroupItems(that: GroupingHelper, options, loadedGroupCount, expandedInfo, groupLevel, data) {
if (!options.isCustomLoading) {
expandedInfo = {};

Expand All @@ -218,7 +220,7 @@ function loadGroupItems(that, options, loadedGroupCount, expandedInfo, groupLeve
}
}

function loadExpandedGroups(that, options, expandedInfo, loadedGroupCount, groupLevel, data) {
function loadExpandedGroups(that: GroupingHelper, options, expandedInfo, loadedGroupCount, groupLevel, data) {
const groups = options.group || [];
const currentGroup = groups[groupLevel + 1];
const deferreds: any[] = [];
Expand All @@ -245,17 +247,20 @@ function loadExpandedGroups(that, options, expandedInfo, loadedGroupCount, group
loadOptions.take = expandedInfo.take;
}

const loadResult = loadOptions.take === 0 ? [] : that._dataSource.loadFromStore(loadOptions);
const loadDeferred = loadOptions.take === 0
? { data: [] as RawItemData[] }
: that._dataSource.customLoader.loadFromStore(loadOptions);

when(loadResult).done((data) => {
const item = expandedInfo.items[expandedItemIndex];
when(loadDeferred)
.done((loadResult) => {
const item = expandedInfo.items[expandedItemIndex];

applyContinuationToGroupItem(options, expandedInfo, groupLevel, expandedItemIndex);
applyContinuationToGroupItem(options, expandedInfo, groupLevel, expandedItemIndex);

item.items = data;
});
item.items = loadResult.data;
});

deferreds.push(loadResult);
deferreds.push(loadDeferred);
});

when.apply(null, deferreds).done(() => {
Expand All @@ -265,7 +270,7 @@ function loadExpandedGroups(that, options, expandedInfo, loadedGroupCount, group
});
}

function loadLastLevelGroupItems(that, options, expandedInfo, data) {
function loadLastLevelGroupItems(that: GroupingHelper, options, expandedInfo, data) {
const expandedFilters: any[] = [];
const groups = options.group || [];

Expand All @@ -289,15 +294,23 @@ function loadLastLevelGroupItems(that, options, expandedInfo, data) {
filter,
});

// @ts-expect-error badly typed GroupingHelper.dataSource
const isPagingLocal = that._dataSource.isLastLevelGroupItemsPagingLocal();

if (!isPagingLocal) {
loadOptions.skip = expandedInfo.skip;
loadOptions.take = expandedInfo.take;
}

when(expandedInfo.take === 0 ? [] : that._dataSource.loadFromStore(loadOptions)).done((items) => {
const loadDeferred = expandedInfo.take === 0
? { data: [] as RawItemData[] }
: that._dataSource.customLoader.loadFromStore(loadOptions);

when(loadDeferred).done((loadResult) => {
let items = loadResult.data;

if (isPagingLocal) {
// @ts-expect-error badly typed GroupingHelper.dataSource
items = that._dataSource.sortLastLevelGroupItems(items, groups, expandedInfo.paths);
items = expandedInfo.skip ? items.slice(expandedInfo.skip) : items;
items = expandedInfo.take ? items.slice(0, expandedInfo.take) : items;
Expand All @@ -313,18 +326,18 @@ function loadLastLevelGroupItems(that, options, expandedInfo, data) {
}).fail(options.data.reject);
}

const loadGroupTotalCount = function (dataSource, options) {
const loadGroupTotalCount = function (dataSource: DataSourceAdapter, options) {
// @ts-expect-error
const d = new Deferred();
const isGrouping = !!(options.group && options.group.length);
const loadOptions = extend({
skip: 0, take: 1, requireGroupCount: isGrouping, requireTotalCount: !isGrouping,
}, options, { group: isGrouping ? options.group : null });

dataSource.load(loadOptions).done((data, extra) => {
const count = extra && (isGrouping ? extra.groupCount : extra.totalCount);
dataSource.customLoader.load(loadOptions).done(({ extra }) => {
const count: number | undefined = extra && (isGrouping ? extra.groupCount : extra.totalCount);

if (!isFinite(count)) {
if (count === undefined || !isFinite(count)) {
d.reject(dataErrors.Error(isGrouping ? 'E4022' : 'E4021'));
return;
}
Expand All @@ -338,6 +351,7 @@ export class GroupingHelper extends GroupingHelperCore {
let totalItemsCount = 0;
const totalCount = options.extra && options.extra.totalCount || 0;
const groupCount = options.extra && options.extra.groupCount || 0;
// @ts-expect-error badly typedDataSourceAdapter.pageSize
const pageSize = this._dataSource.pageSize();
const isVirtualPaging = this._isVirtualPaging();

Expand Down Expand Up @@ -369,6 +383,7 @@ export class GroupingHelper extends GroupingHelperCore {
private _updatePagingOptions(options, callback?) {
const that = this;
const isVirtualPaging = that._isVirtualPaging();
// @ts-expect-error badly typedDataSourceAdapter.pageSize
const pageSize = that._dataSource.pageSize();
const skips: any[] = [];
const takes: any[] = [];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { normalizeSortingInfo } from '@js/common/data/utils';
import $ from '@js/core/renderer';
import { when } from '@js/core/utils/deferred';
import type DataSourceAdapter from '@ts/grids/grid_core/data_source_adapter/m_data_source_adapter';
import gridCoreUtils from '@ts/grids/grid_core/m_utils';

import gridCore from '../m_core';
Expand Down Expand Up @@ -102,15 +103,15 @@ const calculateItemsCount = function (that, items, groupsCount) {
};

export class GroupingHelper {
protected readonly _dataSource: any;
public readonly _dataSource: DataSourceAdapter;

private _groupsInfo: any;

private _totalCountCorrection: any;

protected _group: any;

constructor(dataSourceAdapter) {
constructor(dataSourceAdapter: DataSourceAdapter) {
this._dataSource = dataSourceAdapter;
this.reset();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@ import { toComparable } from '@js/core/utils/data';
import { Deferred, when } from '@js/core/utils/deferred';
import { extend } from '@js/core/utils/extend';
import { each } from '@js/core/utils/iterator';
import type DataSourceAdapter from '@ts/grids/grid_core/data_source_adapter/m_data_source_adapter';

import dataGridCore from '../m_core';
import { createGroupFilter } from '../m_utils';
import { createOffsetFilter, GroupingHelper as GroupingHelperCore } from './m_grouping_core';
import type { DataItem, GroupInfoData, GroupItemData } from './types';

const loadTotalCount = function (dataSource, options) {
const loadTotalCount = function (dataSource: DataSourceAdapter, options) {
// @ts-expect-error
const d = new Deferred();
const loadOptions = extend({ skip: 0, take: 1, requireTotalCount: true }, options);

dataSource.load(loadOptions).done((data, extra) => {
d.resolve(extra && extra.totalCount);
dataSource.customLoader.load(loadOptions).done(({ extra }) => {
d.resolve(extra!.totalCount);
}).fail(d.reject.bind(d));
return d;
};
Expand Down Expand Up @@ -377,10 +378,13 @@ export class GroupingHelper extends GroupingHelperCore {
private changeRowExpand(path) {
const that = this;
const dataSource = that._dataSource;
// @ts-expect-error badly typedDataSourceAdapter.beginPageIndex
const beginPageIndex = dataSource.beginPageIndex
// @ts-expect-error badly typedDataSourceAdapter.beginPageIndex
? dataSource.beginPageIndex()
: dataSource.pageIndex();
const dataSourceItems = dataSource.items();
// @ts-expect-error badly typedDataSourceAdapter.pageSize
const offset = correctSkipLoadOption(that, beginPageIndex * dataSource.pageSize());
const groupInfo = that.findGroupInfo(path);
let groupCountQuery;
Expand Down Expand Up @@ -418,6 +422,7 @@ export class GroupingHelper extends GroupingHelperCore {
}
that.updateTotalItemsCount();
}).fail(function () {
// @ts-expect-error badly typedDataSourceAdapter._eventsStrategy
dataSource._eventsStrategy.fireEvent('loadError', arguments);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import $ from '@js/core/renderer';
import { extend } from '@js/core/utils/extend';
import { each } from '@js/core/utils/iterator';
import { isDefined, isPlainObject } from '@js/core/utils/type';
import type { DataSource } from '@ts/data/data_source/types';
import type { DataSource } from '@ts/data/data_source/data_source';
import type { ColumnsController } from '@ts/grids/grid_core/columns_controller/m_columns_controller';
import type DataSourceAdapter from '@ts/grids/grid_core/data_source_adapter/m_data_source_adapter';
import type { RemoteOperationsOptions } from '@ts/grids/grid_core/data_source_adapter/types';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const createCallbacks = (): {
failure: jest.fn((message?: string) => ({ status: 'failure' as const, message: message ?? '' })),
});

// The local "allPages" path calls loadAll(), which defers behind the grid's
// The local "allPages" path calls loadAllItems(), which defers behind the grid's
// loading timer. Under fake timers that timer must be advanced while the
// command is in flight, otherwise the awaited result never settles.
const executeWithTimers = async (
Expand Down Expand Up @@ -669,9 +669,9 @@ describe('selectionByIndexesCommand', () => {
});

describe('scope "allPages" — local paging', () => {
it('resolves keys via loadAll (no store.load) and selects with preserve=true', async () => {
it('resolves keys via loadAllItems (no store.load) and selects with preserve=true', async () => {
const instance = await createGrid();
const loadAllSpy = jest.spyOn(instance.getController('data'), 'loadAll');
const loadAllItemsSpy = jest.spyOn(instance.getController('data'), 'loadAllItems');
const loadSpy = jest.spyOn(instance.getDataSource().store(), 'load');
const selectSpy = jest.spyOn(instance, 'selectRows').mockReturnValue(Promise.resolve([]) as never);
const callbacks = createCallbacks();
Expand All @@ -682,13 +682,13 @@ describe('selectionByIndexesCommand', () => {
}),
);

expect(loadAllSpy).toHaveBeenCalled();
expect(loadAllItemsSpy).toHaveBeenCalled();
expect(loadSpy).not.toHaveBeenCalled();
expect(selectSpy).toHaveBeenCalledWith([1, 3], true);
expect(result.status).toBe('success');
});

it('resolves keys via loadAll and calls deselectRows when deselecting', async () => {
it('resolves keys via loadAllItems and calls deselectRows when deselecting', async () => {
const instance = await createGrid();
const deselectSpy = jest.spyOn(instance, 'deselectRows').mockReturnValue(Promise.resolve([]) as never);
const callbacks = createCallbacks();
Expand Down Expand Up @@ -738,7 +738,7 @@ describe('selectionByIndexesCommand', () => {
expect(result.status).toBe('success');
});

it('indexes within the filtered dataset (combined filter applied via loadAll)', async () => {
it('indexes within the filtered dataset (combined filter applied via loadAllItems)', async () => {
const instance = await createGrid({
columns: [
{ dataField: 'id', dataType: 'number' },
Expand Down
Loading
Loading