Skip to content

Commit

Permalink
DataGrid - Add deferred selection case sensitivity support (T1234676) (
Browse files Browse the repository at this point in the history
…#27967)

Co-authored-by: Ilya Vinogradov <[email protected]>
  • Loading branch information
pomahtri and williamvinogradov authored Sep 3, 2024
1 parent 5f5238a commit c70c3c4
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 6 deletions.
93 changes: 93 additions & 0 deletions e2e/testcafe-devextreme/tests/dataGrid/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,96 @@ test('Select rows by shift should work when grid has real time updates', async (
pageSize: 10,
},
}));

// --- T1234676 ---

const data = [
{ ID: 'aaa', Name: 'Name 1' },
{ ID: 'AAA', Name: 'Name 2' },
{ ID: 'BBB', Name: 'Name 3' },
];
const DATA_GRID_SELECTOR = '#container';
(['base', undefined] as ('base' | undefined)[]).forEach((sensitivity) => {
test(`Deferred selection should work correctly with deferred sensitivity: ${sensitivity}`, async (t) => {
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);
const checkBoxCell = dataGrid.getDataCell(0, 0);
const firstRow = dataGrid.getDataRow(0);
const secondRow = dataGrid.getDataRow(1);

await t.click(checkBoxCell.element);

await t
.expect(firstRow.isSelected).ok()
.expect(secondRow.isSelected).ok();
}).before(() => createWidget('dxDataGrid', {
dataSource: data,
keyExpr: 'ID',
columns: ['ID', 'Name'],
showBorders: true,
selection: {
mode: 'multiple',
deferred: true,
sensitivity,
},
}));
});

test('Deferred selection should work correctly with deferred sensitivity: \'case\'', async (t) => {
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);
const checkBoxCell = dataGrid.getDataCell(0, 0);
const firstRow = dataGrid.getDataRow(0);
const secondRow = dataGrid.getDataRow(1);

await t.click(checkBoxCell.element);

await t
.expect(firstRow.isSelected).ok()
.expect(secondRow.isSelected).notOk();
}).before(() => createWidget('dxDataGrid', {
dataSource: data,
keyExpr: 'ID',
columns: ['ID', 'Name'],
showBorders: true,
selection: {
mode: 'multiple',
deferred: true,
sensitivity: 'case',
},
}));

test('Sensitivity option change should be correctly handled during runtime change', async (t) => {
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);
const checkBoxCell = dataGrid.getDataCell(0, 0);
const firstRow = dataGrid.getDataRow(0);
const secondRow = dataGrid.getDataRow(1);

await t.click(checkBoxCell.element);

await t
.expect(firstRow.isSelected).ok()
.expect(secondRow.isSelected).ok();

await dataGrid.apiChangeSensitivity('case');

await t
.expect(firstRow.isSelected).notOk()
.expect(secondRow.isSelected).notOk();

await t.click(checkBoxCell.element);

await t
.expect(firstRow.isSelected).ok()
.expect(secondRow.isSelected).notOk();
}).before(() => createWidget('dxDataGrid', {
dataSource: data,
keyExpr: 'ID',
columns: ['ID', 'Name'],
showBorders: true,
selection: {
mode: 'multiple',
deferred: true,
sensitivity: 'base',
},
}));

// ---
8 changes: 4 additions & 4 deletions packages/devextreme-angular/src/ui/data-grid/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { UserDefinedElement } from 'devextreme/core/element';
import { Store } from 'devextreme/data';
import DataSource, { Options as DataSourceOptions } from 'devextreme/data/data_source';
import { Format } from 'devextreme/localization';
import { AdaptiveDetailRowPreparingEvent, CellClickEvent, CellDblClickEvent, CellHoverChangedEvent, CellPreparedEvent, ContentReadyEvent, ContextMenuPreparingEvent, DataErrorOccurredEvent, DataGridExportFormat, DataGridScrollMode, DisposingEvent, dxDataGridColumn, dxDataGridToolbar, EditCanceledEvent, EditCancelingEvent, EditingStartEvent, EditorPreparedEvent, EditorPreparingEvent, ExportingEvent, FocusedCellChangedEvent, FocusedCellChangingEvent, FocusedRowChangedEvent, FocusedRowChangingEvent, InitializedEvent, InitNewRowEvent, KeyDownEvent, OptionChangedEvent, RowClickEvent, RowCollapsedEvent, RowCollapsingEvent, RowDblClickEvent, RowExpandedEvent, RowExpandingEvent, RowInsertedEvent, RowInsertingEvent, RowPreparedEvent, RowRemovedEvent, RowRemovingEvent, RowUpdatedEvent, RowUpdatingEvent, RowValidatingEvent, SavedEvent, SavingEvent, SelectionChangedEvent, ToolbarPreparingEvent } from 'devextreme/ui/data_grid';
import { AdaptiveDetailRowPreparingEvent, CellClickEvent, CellDblClickEvent, CellHoverChangedEvent, CellPreparedEvent, ContentReadyEvent, ContextMenuPreparingEvent, DataErrorOccurredEvent, DataGridExportFormat, DataGridScrollMode, DisposingEvent, dxDataGridColumn, dxDataGridToolbar, EditCanceledEvent, EditCancelingEvent, EditingStartEvent, EditorPreparedEvent, EditorPreparingEvent, ExportingEvent, FocusedCellChangedEvent, FocusedCellChangingEvent, FocusedRowChangedEvent, FocusedRowChangingEvent, InitializedEvent, InitNewRowEvent, KeyDownEvent, OptionChangedEvent, RowClickEvent, RowCollapsedEvent, RowCollapsingEvent, RowDblClickEvent, RowExpandedEvent, RowExpandingEvent, RowInsertedEvent, RowInsertingEvent, RowPreparedEvent, RowRemovedEvent, RowRemovingEvent, RowUpdatedEvent, RowUpdatingEvent, RowValidatingEvent, SavedEvent, SavingEvent, SelectionChangedEvent, SelectionSensitivity, ToolbarPreparingEvent } from 'devextreme/ui/data_grid';
import { Properties as dxFilterBuilderOptions } from 'devextreme/ui/filter_builder';
import { Properties as dxFormOptions } from 'devextreme/ui/form';
import { Properties as dxPopupOptions } from 'devextreme/ui/popup';
Expand Down Expand Up @@ -896,10 +896,10 @@ export class DxDataGridComponent<TRowData = any, TKey = any> extends DxComponent
*/
@Input()
get selection(): { allowSelectAll?: boolean, deferred?: boolean, mode?: SingleMultipleOrNone, selectAllMode?: SelectAllMode, showCheckBoxesMode?: SelectionColumnDisplayMode } {
get selection(): { allowSelectAll?: boolean, deferred?: boolean, mode?: SingleMultipleOrNone, selectAllMode?: SelectAllMode, sensitivity?: SelectionSensitivity, showCheckBoxesMode?: SelectionColumnDisplayMode } {
return this._getOption('selection');
}
set selection(value: { allowSelectAll?: boolean, deferred?: boolean, mode?: SingleMultipleOrNone, selectAllMode?: SelectAllMode, showCheckBoxesMode?: SelectionColumnDisplayMode }) {
set selection(value: { allowSelectAll?: boolean, deferred?: boolean, mode?: SingleMultipleOrNone, selectAllMode?: SelectAllMode, sensitivity?: SelectionSensitivity, showCheckBoxesMode?: SelectionColumnDisplayMode }) {
this._setOption('selection', value);
}

Expand Down Expand Up @@ -1850,7 +1850,7 @@ export class DxDataGridComponent<TRowData = any, TKey = any> extends DxComponent
* This member supports the internal infrastructure and is not intended to be used directly from your code.
*/
@Output() selectionChange: EventEmitter<{ allowSelectAll?: boolean, deferred?: boolean, mode?: SingleMultipleOrNone, selectAllMode?: SelectAllMode, showCheckBoxesMode?: SelectionColumnDisplayMode }>;
@Output() selectionChange: EventEmitter<{ allowSelectAll?: boolean, deferred?: boolean, mode?: SingleMultipleOrNone, selectAllMode?: SelectAllMode, sensitivity?: SelectionSensitivity, showCheckBoxesMode?: SelectionColumnDisplayMode }>;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {

import { SelectAllMode, SingleMultipleOrNone } from 'devextreme/common';
import { SelectionColumnDisplayMode } from 'devextreme/common/grids';
import { SelectionSensitivity } from 'devextreme/ui/data_grid';

@Component({
template: ''
Expand Down Expand Up @@ -54,6 +55,13 @@ export abstract class DxoColumnChooserSelectionConfig extends NestedOption {
this._setOption('selectAllMode', value);
}

get sensitivity(): SelectionSensitivity {
return this._getOption('sensitivity');
}
set sensitivity(value: SelectionSensitivity) {
this._setOption('sensitivity', value);
}

get showCheckBoxesMode(): SelectionColumnDisplayMode {
return this._getOption('showCheckBoxesMode');
}
Expand Down
1 change: 1 addition & 0 deletions packages/devextreme-angular/src/ui/nested/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { DxoColumnChooserSelectionConfig } from './base/column-chooser-selection
'deferred',
'mode',
'selectAllMode',
'sensitivity',
'showCheckBoxesMode'
]
})
Expand Down
2 changes: 2 additions & 0 deletions packages/devextreme-react/src/data-grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,7 @@ type IDataGridSelectionProps = React.PropsWithChildren<{
deferred?: boolean;
mode?: "single" | "multiple" | "none";
selectAllMode?: "allPages" | "page";
sensitivity?: "base" | "accent" | "case" | "variant";
showCheckBoxesMode?: "always" | "none" | "onClick" | "onLongTap";
}>
const _componentDataGridSelection = memo(
Expand Down Expand Up @@ -2351,6 +2352,7 @@ type ISelectionProps = React.PropsWithChildren<{
deferred?: boolean;
mode?: "single" | "multiple" | "none";
selectAllMode?: "allPages" | "page";
sensitivity?: "base" | "accent" | "case" | "variant";
showCheckBoxesMode?: "always" | "none" | "onClick" | "onLongTap";
recursive?: boolean;
selectByClick?: boolean;
Expand Down
4 changes: 4 additions & 0 deletions packages/devextreme-vue/src/data-grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1032,13 +1032,15 @@ const DxDataGridSelection = createConfigurationComponent({
"update:deferred": null,
"update:mode": null,
"update:selectAllMode": null,
"update:sensitivity": null,
"update:showCheckBoxesMode": null,
},
props: {
allowSelectAll: Boolean,
deferred: Boolean,
mode: String,
selectAllMode: String,
sensitivity: String,
showCheckBoxesMode: String
}
});
Expand Down Expand Up @@ -2485,6 +2487,7 @@ const DxSelection = createConfigurationComponent({
"update:recursive": null,
"update:selectAllMode": null,
"update:selectByClick": null,
"update:sensitivity": null,
"update:showCheckBoxesMode": null,
},
props: {
Expand All @@ -2494,6 +2497,7 @@ const DxSelection = createConfigurationComponent({
recursive: Boolean,
selectAllMode: String,
selectByClick: Boolean,
sensitivity: String,
showCheckBoxesMode: String
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ export class SelectionController extends modules.Controller {
selectionFilter: this.option('selectionFilter'),
ignoreDisabledItems: true,
isVirtualPaging: virtualPaging,
sensitivity: this.option('selection.sensitivity'),
allowLoadByRange() {
const hasGroupColumns = columnsController.getGroupColumns().length > 0;
return virtualPaging && !legacyScrollingMode && !hasGroupColumns && allowSelectAll && !deferred;
Expand Down Expand Up @@ -407,13 +408,19 @@ export class SelectionController extends modules.Controller {
public optionChanged(args) {
super.optionChanged(args);

const selectionOptionsExists = !!this._selection?.options;

// eslint-disable-next-line default-case
switch (args.name) {
case 'selection': {
const oldSelectionMode = this._selectionMode;

this.init();

if (selectionOptionsExists && args.fullName === 'selection.sensitivity') {
this._selection.options.sensitivity = args.value;
}

if (args.fullName !== 'selection.showCheckBoxesMode') {
const selectionMode = this._selectionMode;
let selectedRowKeys: any = this.option('selectedRowKeys');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,20 @@ export default class DeferredStrategy extends SelectionStrategy {
}

isItemKeySelected(itemData) {
const { selectionFilter } = this.options;
const { selectionFilter, sensitivity } = this.options;

if (!selectionFilter) {
return true;
}

return !!dataQuery([itemData]).filter(selectionFilter).toArray().length;
const queryParams = {
langParams: {
collatorOptions: {
sensitivity,
},
},
};
return !!dataQuery([itemData], queryParams).filter(selectionFilter).toArray().length;
}

_getKeyExpr() {
Expand Down
9 changes: 9 additions & 0 deletions packages/devextreme/js/ui/data_grid.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1988,6 +1988,9 @@ export type Scrolling = ScrollingBase & {
*/
export type dxDataGridSelection = Selection;

/** @public */
export type SelectionSensitivity = 'base' | 'accent' | 'case' | 'variant';

/** @public */
export type Selection = SelectionBase & {
/**
Expand All @@ -1996,6 +1999,12 @@ export type Selection = SelectionBase & {
* @public
*/
deferred?: boolean;
/**
* @docid dxDataGridOptions.selection.sensitivity
* @default "base"
* @public
*/
sensitivity?: SelectionSensitivity;
/**
* @docid dxDataGridOptions.selection.selectAllMode
* @default "allPages"
Expand Down
1 change: 1 addition & 0 deletions packages/devextreme/js/ui/data_grid_types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ export {
Editing,
EditingTexts,
Scrolling,
SelectionSensitivity,
Selection,
Column,
ColumnButton,
Expand Down
5 changes: 5 additions & 0 deletions packages/devextreme/ts/dx.all.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11568,6 +11568,10 @@ declare module DevExpress.ui {
* [descr:dxDataGridOptions.selection.deferred]
*/
deferred?: boolean;
/**
* [descr:dxDataGridOptions.selection.sensitivity]
*/
sensitivity?: SelectionSensitivity;
/**
* [descr:dxDataGridOptions.selection.selectAllMode]
*/
Expand All @@ -11590,6 +11594,7 @@ declare module DevExpress.ui {
TKey = any
> = DevExpress.events.EventInfo<dxDataGrid<TRowData, TKey>> &
DevExpress.common.grids.SelectionChangedInfo<TRowData, TKey>;
export type SelectionSensitivity = 'base' | 'accent' | 'case' | 'variant';
/**
* [descr:dxDataGridSortByGroupSummaryInfoItem]
*/
Expand Down
13 changes: 13 additions & 0 deletions packages/testcafe-models/dataGrid/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ClientFunction, Selector } from 'testcafe';
import DataGridInstance from 'devextreme/ui/data_grid';
import type { SelectionSensitivity } from 'devextreme/ui/data_grid';
import Widget from '../internal/widget';
import Toolbar from '../toolbar';
import DataRow from './data/row';
Expand Down Expand Up @@ -788,4 +789,16 @@ export default class DataGrid extends Widget {
getSummaryTotalElement(nth = 0): Selector {
return this.element().find(`.${CLASS.summaryTotal}`).nth(nth);
}

apiChangeSensitivity(
sensitivity: SelectionSensitivity,
): Promise<void> {
const { getInstance } = this;
return ClientFunction(
() => {
(getInstance() as DataGridInstance).option('selection.sensitivity', sensitivity);
},
{ dependencies: { getInstance, sensitivity } },
)();
}
}

0 comments on commit c70c3c4

Please sign in to comment.