Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import type {
UpdateItemChange,
UserState,
} from './types';
import { resolvePaginate, syncPaging } from './utils/paging';
import { syncPaging } from './utils/paging';
import { getRefreshOptions } from './utils/refresh';
import {
attachChangedItems,
Expand Down Expand Up @@ -275,7 +275,6 @@ export class DataController extends modules.Controller {
case 'remoteOperations':
case 'keyExpr':
case 'dataSource':
case 'scrolling':
args.handled = true;
this.reset();
break;
Expand Down Expand Up @@ -617,19 +616,31 @@ export class DataController extends modules.Controller {
}

private applyPagingOptions(dataSource: PagingDataSource): PagingChanges {
const { scrolling, paging } = this.option();
const { paging } = this.option();

// Not paging state to reconcile, but a per-load request flag: infinite
// scrolling detects the last page locally and needs no grand total.
dataSource.requireTotalCount(scrolling?.mode !== 'infinite');
dataSource.requireTotalCount(this.requiresTotalCount());

return syncPaging(dataSource, {
paginate: resolvePaginate(paging?.enabled, scrolling?.mode),
paginate: this.resolvePaginate(paging?.enabled),
pageSize: paging?.pageSize,
pageIndex: paging?.pageIndex,
});
}

/**
* @extended: virtual_scrolling
*/
protected resolvePaginate(enabled: boolean | undefined): boolean | undefined {
return enabled;
}

/**
* @extended: virtual_scrolling
*/
protected requiresTotalCount(): boolean {
return true;
}

/**
* @extended: state_storing, virtual_scrolling
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,7 @@
import { describe, expect, it } from '@jest/globals';

import type { PagingDataSource } from '../../types';
import { resolvePaginate, syncPaging } from '../paging';

describe('resolvePaginate', () => {
it.each([
{ enabled: true, scrollingMode: 'standard', expected: true },
{ enabled: false, scrollingMode: 'standard', expected: false },
// Virtual and infinite scrolling paginate even with paging disabled.
{ enabled: false, scrollingMode: 'virtual', expected: true },
{ enabled: false, scrollingMode: 'infinite', expected: true },
{ enabled: true, scrollingMode: 'virtual', expected: true },
{ enabled: true, scrollingMode: 'infinite', expected: true },
])('should be $expected for enabled=$enabled, scrolling.mode=$scrollingMode', ({
enabled, scrollingMode, expected,
}) => {
expect(resolvePaginate(enabled, scrollingMode)).toBe(expected);
});

// An undefined `paging.enabled` leaves the data source's paginate alone,
// even in a mode that would otherwise force it on.
it.each(['standard', 'virtual', 'infinite'])(
'should be undefined when enabled is undefined in %s mode',
(scrollingMode) => {
expect(resolvePaginate(undefined, scrollingMode)).toBeUndefined();
},
);
});
import { syncPaging } from '../paging';

const createDataSourceMock = (
state: { paginate: boolean; pageSize: number; pageIndex: number },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
import type { PagingChanges, PagingDataSource, SyncPagingOptions } from '../types';

export function resolvePaginate(
enabled: boolean | undefined,
scrollingMode: string | undefined,
): boolean | undefined {
if (enabled === undefined) {
return undefined;
}

return enabled || scrollingMode === 'virtual' || scrollingMode === 'infinite';
}

export function syncPaging(
dataSource: PagingDataSource,
options: SyncPagingOptions,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {
afterEach, beforeEach, describe, expect, it, jest,
} from '@jest/globals';
import type { DataGridScrollMode } from '@js/ui/data_grid';
import {
afterTest,
beforeTest,
createDataGrid,
} from '@ts/grids/grid_core/__tests__/__mock__/helpers/utils';
import type { DataController } from '@ts/grids/grid_core/data_controller/data_controller';

declare class ExposedDataController extends DataController {
public resolvePaginate(enabled: boolean | undefined): boolean | undefined;

public requiresTotalCount(): boolean;
}

const withScrollingMode = async (mode: DataGridScrollMode): Promise<ExposedDataController> => {
const { instance } = await createDataGrid({ dataSource: [], scrolling: { mode } });

return instance.getController('data') as unknown as ExposedDataController;
};

describe('Virtual scrolling data controller paging', () => {
beforeEach(beforeTest);
afterEach(afterTest);

describe('resolvePaginate', () => {
it.each<{ mode: DataGridScrollMode; enabled: boolean; expected: boolean }>([
{ mode: 'standard', enabled: true, expected: true },
{ mode: 'standard', enabled: false, expected: false },
{ mode: 'virtual', enabled: false, expected: true },
{ mode: 'infinite', enabled: false, expected: true },
])('should be $expected in $mode mode with enabled=$enabled', async ({
mode, enabled, expected,
}) => {
const dataController = await withScrollingMode(mode);

expect(dataController.resolvePaginate(enabled)).toBe(expected);
});

it.each<DataGridScrollMode>(['standard', 'virtual', 'infinite'])(
'should leave paginate untouched when enabled is undefined in %s mode',
async (mode) => {
const dataController = await withScrollingMode(mode);

expect(dataController.resolvePaginate(undefined)).toBeUndefined();
},
);
});

describe('requiresTotalCount', () => {
it.each<{ mode: DataGridScrollMode; expected: boolean }>([
{ mode: 'standard', expected: true },
{ mode: 'virtual', expected: true },
{ mode: 'infinite', expected: false },
])('should be $expected in $mode mode', async ({ mode, expected }) => {
const dataController = await withScrollingMode(mode);

expect(dataController.requiresTotalCount()).toBe(expected);
});
});

it('should reset the data controller when the scrolling option changes', async () => {
const { instance } = await createDataGrid({ dataSource: [] });
const dataController = instance.getController('data');
const resetSpy = jest.spyOn(dataController, 'reset');

instance.option('scrolling.mode', 'virtual');

expect(resetSpy).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import type {
DataChange, PagingOptionName, PagingResult, ProcessedItem, RefreshOptions,
} from '@ts/grids/grid_core/data_controller/types';
import type { RawItemData } from '@ts/grids/grid_core/data_source_adapter/types';
import type { ModuleType } from '@ts/grids/grid_core/m_types';
import type { ModuleType, OptionChanged } from '@ts/grids/grid_core/m_types';
import type { VirtualItemsCount } from '@ts/grids/grid_core/virtual_data_loader/types';

import gridCoreUtils from '../../m_utils';
Expand Down Expand Up @@ -933,6 +933,28 @@ export const virtualScrollingDataControllerExtender = (
return result;
}

protected resolvePaginate(enabled: boolean | undefined): boolean | undefined {
if (enabled === undefined) {
return undefined;
}

return enabled || isVirtualPaging(this);
}

protected requiresTotalCount(): boolean {
return !isInfiniteMode(this);
}

public optionChanged(args: OptionChanged): void {
if (args.name === 'scrolling') {
args.handled = true;
this.reset();
return;
}

super.optionChanged(args);
}

public isEmpty(): boolean {
return this.option(LEGACY_SCROLLING_MODE) === false ? !this.items(true).length : super.isEmpty.apply(this, arguments as any);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ QUnit.module('State Storing', {
keyExpr: 'id',
parentIdExpr: 'parentId',
loadingTimeout: null,
paging: {
enabled: true
},
scrolling: {
mode: 'virtual'
}
Expand Down
Loading