Skip to content

Commit a02d81f

Browse files
authored
DataGrid — Fixed group header overlaps group summary values when columnRenderingMode="virtual" (T1324988) (#33077)
1 parent 23dbb08 commit a02d81f

4 files changed

Lines changed: 87 additions & 3 deletions

File tree

packages/devextreme/js/__internal/grids/data_grid/summary/__tests__/m_summary.integration.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,72 @@ describe('Summary', () => {
1313
beforeEach(beforeTest);
1414
afterEach(afterTest);
1515

16+
describe('alignByColumn with virtual column rendering (T1324988)', () => {
17+
const COLUMN_COUNT = 100;
18+
19+
const dynamicColumns = Array.from({ length: COLUMN_COUNT }, (_, i) => ({
20+
dataField: `field${i}`,
21+
width: 100,
22+
}));
23+
24+
const columns = [
25+
{
26+
dataField: 'company', width: 100, fixed: true, fixedPosition: 'left' as const,
27+
},
28+
{ dataField: 'state', width: 100, groupIndex: 0 },
29+
...dynamicColumns,
30+
];
31+
32+
const groupItems = dynamicColumns.map((col) => ({
33+
column: col.dataField,
34+
summaryType: 'sum' as const,
35+
alignByColumn: true,
36+
}));
37+
38+
const dataSource = [
39+
{
40+
id: 1,
41+
company: 'Company A',
42+
state: 'Arkansas',
43+
...Object.fromEntries(dynamicColumns.map((col, i) => [col.dataField, i])),
44+
},
45+
];
46+
47+
it('group row cell colSpan should be 1 after horizontal scroll', async () => {
48+
const { component } = await createDataGrid({
49+
dataSource,
50+
keyExpr: 'id',
51+
width: 500,
52+
showBorders: true,
53+
columns,
54+
summary: { groupItems },
55+
scrolling: {
56+
columnRenderingMode: 'virtual',
57+
},
58+
});
59+
60+
await flushAsync();
61+
62+
const beforeScrollCell = component.getDataCell(1, 3);
63+
expect(beforeScrollCell.getText()).toBe('1');
64+
65+
const scrollContainer = component.getScrollableContainer();
66+
scrollContainer.scrollLeft = 5000;
67+
scrollContainer.dispatchEvent(new Event('scroll'));
68+
await flushAsync();
69+
70+
expect(scrollContainer.scrollLeft).toBe(5000);
71+
72+
const afterScrollCell = component.getDataCell(1, 3);
73+
expect(afterScrollCell.getText()).toBe('48');
74+
75+
const groupCells = component.getGroupRow(0).getCells();
76+
const colSpan = Number(groupCells[1].getAttribute('colSpan')) || 1;
77+
78+
expect(colSpan).toBe(1);
79+
});
80+
});
81+
1682
describe('column lookup map performance optimization (T1316562)', () => {
1783
const SUMMARY_COUNT = 100;
1884
const GROUP_COUNT = 4;

packages/devextreme/js/__internal/grids/data_grid/summary/m_summary.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -938,16 +938,23 @@ const rowsView = (Base: ModuleType<RowsView>) => class SummaryRowsViewExtender e
938938
}
939939
}
940940

941-
private _hasAlignByColumnSummaryItems(columnIndex, options) {
942-
return !isDefined(options.columns[columnIndex].groupIndex) && options.row.summaryCells[columnIndex].length;
941+
private _hasAlignByColumnSummaryItems(columnIndex, options): boolean {
942+
const column = options.columns[columnIndex];
943+
const isGrouped = isDefined(column.groupIndex);
944+
const isVirtual = column.command === 'virtual';
945+
const hasSummaryCells = !!options.row.summaryCells[columnIndex].length;
946+
return !isGrouped && (isVirtual || hasSummaryCells);
943947
}
944948

945949
private _getAlignByColumnCellCount(groupCellColSpan, options) {
946950
let alignByColumnCellCount = 0;
947951

948952
for (let i = 1; i < groupCellColSpan; i++) {
949953
const columnIndex = options.row.summaryCells.length - i;
950-
alignByColumnCellCount = this._hasAlignByColumnSummaryItems(columnIndex, options) ? i : alignByColumnCellCount;
954+
const hasAlignBySummary = this._hasAlignByColumnSummaryItems(columnIndex, options);
955+
if (hasAlignBySummary) {
956+
alignByColumnCellCount = i;
957+
}
951958
}
952959

953960
return alignByColumnCellCount;

packages/devextreme/js/__internal/grids/grid_core/__tests__/__mock__/model/grid_core.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const SELECTORS = {
2222
headerRowClass: 'dx-header-row',
2323
dataRowClass: 'dx-data-row',
2424
groupRowClass: 'dx-group-row',
25+
scrollableContainer: 'dx-scrollable-container',
2526
aiDialog: 'dx-aidialog',
2627
aiPromptEditor: 'dx-ai-prompt-editor',
2728
toast: 'dx-toast',
@@ -105,6 +106,10 @@ export abstract class GridCoreModel<TInstance = GridBase | CardView> {
105106
return new GroupRowModel(this.getGroupRows()[rowIndex]);
106107
}
107108

109+
public getScrollableContainer(): HTMLElement {
110+
return this.root.querySelector(`.${SELECTORS.scrollableContainer}`) as HTMLElement;
111+
}
112+
108113
public getHeaderByText(text: string): dxElementWrapper {
109114
return $(Array.from(this.getHeaderCells()).find((el) => $(el).text().includes(text)));
110115
}

packages/devextreme/js/__internal/grids/grid_core/__tests__/__mock__/model/row/group_row.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,10 @@ export class GroupRowModel {
1515

1616
return row.querySelector(`.${SELECTORS.expandCell}`) as HTMLElement;
1717
}
18+
19+
public getCells(): NodeListOf<HTMLElement> {
20+
const row = this.getElement() as HTMLElement;
21+
22+
return row.querySelectorAll('td');
23+
}
1824
}

0 commit comments

Comments
 (0)