Skip to content

Commit

Permalink
fix(react-grid): fix render of group cell of second level (#3479)
Browse files Browse the repository at this point in the history
  • Loading branch information
Krijovnick authored Jan 17, 2022
1 parent cee2043 commit b7c3919
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 33 deletions.
89 changes: 85 additions & 4 deletions packages/dx-grid-core/src/utils/virtual-table.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ describe('VirtualTableLayout utils', () => {

const result = [
{ column: { type: TABLE_STUB_TYPE, key: `${TABLE_STUB_TYPE.toString()}_0_0` }, colSpan: 1 },
{ column: columns[1], colSpan: 6 },
{ column: columns[1], colSpan: 4 },
{ column: columns[3], colSpan: 1 },
{ column: columns[4], colSpan: 1 },
{ column: columns[5], colSpan: 1 },
Expand Down Expand Up @@ -555,6 +555,36 @@ describe('VirtualTableLayout utils', () => {
expect(getCollapsedCells(columns, spanBoundary, boundaries, getColSpan))
.toEqual(result);
});

it('should not recalculate colSpan when it is not needed', () => {
const columns = [
{ key: 'Symbol(detail)', colSpan: 1 },
{ key: 'Symbol(group_1)', colSpan: 5 },
{ key: 'Symbol(data_1)', colSpan: 1 },
{ key: 'Symbol(data_2)', colSpan: 1 },
{ key: 'Symbol(data_3)', colSpan: 1 },
];
const spanBoundary = [[0, 5]];
const boundaries = [
[0, 0],
[1, 1],
[2, 2],
[3, 3],
[4, 4],
];
const getColSpan = column => column.colSpan;

const result = [
{ column: columns[0], colSpan: 1 },
{ column: columns[1], colSpan: 5 },
{ column: columns[2], colSpan: 1 },
{ column: columns[3], colSpan: 1 },
{ column: columns[4], colSpan: 1 },
];

expect(getCollapsedCells(columns, spanBoundary, boundaries, getColSpan))
.toEqual(result);
});
});

describe('#getCollapsedGrid', () => {
Expand Down Expand Up @@ -582,6 +612,9 @@ describe('VirtualTableLayout utils', () => {
columnsVisibleBoundary: [[1, 3]],
totalRowCount: 9,
offset: 0,
getColSpan: () => 1,
getColumnWidth: column => column.width,
getRowHeight: row => row.height,
};

const result = getCollapsedGrid(args);
Expand Down Expand Up @@ -612,6 +645,8 @@ describe('VirtualTableLayout utils', () => {
columnsVisibleBoundary: [[0, 1]],
totalRowCount: 0,
offset: 0,
getColumnWidth: column => column.width,
getRowHeight: row => row.height,
};
const result = {
columns: args.columns,
Expand Down Expand Up @@ -671,6 +706,8 @@ describe('VirtualTableLayout utils', () => {
},
totalRowCount: 5,
offset: 0,
getColumnWidth: column => column.width,
getRowHeight: row => row.height,
};

const result = getCollapsedGrid(args);
Expand All @@ -683,11 +720,55 @@ describe('VirtualTableLayout utils', () => {
]);

expect(result.rows[0].cells.map(cell => cell.colSpan))
.toEqual([1, 2, 1, 1, 3, 1, 1]);
.toEqual([1, 2, 1, 1, 2, 1, 1]);
expect(result.rows[1].cells.map(cell => cell.colSpan))
.toEqual([1, 6, 1, 1, 1, 1, 1]);
.toEqual([1, 5, 1, 1, 1, 1, 1]);
expect(result.rows[2].cells.map(cell => cell.colSpan))
.toEqual([9, 1, 1, 1, 1, 1, 1]);
.toEqual([7, 1, 1, 1, 1, 1, 1]);
});

it('should return correct cells for second row', () => {
const args = {
rows: [
{ key: 'Symbol(group_1)', height: 40 },
{ key: 'Symbol(group_2)', height: 40 },
],
columns: [
{ key: 'Symbol(group_3)', width: 40 },
{ key: 'Symbol(group_4)', width: 40 },
{ key: 'Symbol(select)', width: 40 },
{ key: 'Symbol(data_3)', width: 40 },
{ key: 'Symbol(data_4)', width: 40 },
{ key: 'Symbol(data_5)', width: 40 },
{ key: 'Symbol(data_6)', width: 40 },
{ key: 'Symbol(data_7)', width: 40 },
{ key: 'Symbol(data_8)', width: 40 },
{ key: 'Symbol(data_9)', width: 40 },
{ key: 'Symbol(data_10)', width: 40 },
],
rowsVisibleBoundary: [0, 1],
columnsVisibleBoundary: [[5, 10]],
getColSpan: (row, column) => {
if (row.key === 'Symbol(group_1)') return 1;
if (row.key === 'Symbol(group_2)' && column.key === 'Symbol(group_4)') return 11;
return 1;
},
totalRowCount: 2,
offset: 0,
getColumnWidth: column => column.width,
getRowHeight: row => row.height,
};

const result = getCollapsedGrid(args);

result.rows[1].cells.forEach((cell, index) => {
if (index === 1) {
expect(cell.colSpan).toEqual(11);
expect(cell.column.key).toEqual('Symbol(group_4)');
} else {
expect(cell.colSpan).toEqual(1);
}
});
});
});

Expand Down
65 changes: 36 additions & 29 deletions packages/dx-grid-core/src/utils/virtual-table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
GetSpecificRenderBoundaryFn,
GetRenderBoundaryFn,
GetRowsVisibleBoundaryFn,
TableRow,
} from '../types';
import { TABLE_FLEX_TYPE, intervalUtil } from '..';

Expand Down Expand Up @@ -233,10 +234,24 @@ export const getCollapsedCells: GetCollapsedCellsFn = (
acc || (spanBoundary[0] <= boundary[0] && boundary[1] <= spanBoundary[1])), false);
if (isSpan) {
const column = columns[boundary[0]];
collapsedCells.push({
column,
colSpan: getColSpan(column),
});
const realColSpan = getColSpan(column);
if (realColSpan + index - 1 !== columns.length) {
const realColSpanEnd = (realColSpan + boundary[0]) - 1;
const colSpanEnd = boundaries.findIndex(
colSpanBoundary => colSpanBoundary[0]
<= realColSpanEnd && realColSpanEnd
<= colSpanBoundary[1],
);
collapsedCells.push({
column,
colSpan: (colSpanEnd - index) + 1,
});
} else {
collapsedCells.push({
column,
colSpan: realColSpan,
});
}
index += 1;
} else {
collapsedCells.push({
Expand All @@ -257,9 +272,9 @@ export const getCollapsedGrid: GetCollapsedGridFn = ({
columns,
rowsVisibleBoundary,
columnsVisibleBoundary,
getColumnWidth = (column: any) => column.width,
getRowHeight = (row: any) => row.height,
getColSpan = () => 1,
getColumnWidth,
getRowHeight,
getColSpan,
totalRowCount,
offset,
}) => {
Expand All @@ -272,13 +287,15 @@ export const getCollapsedGrid: GetCollapsedGridFn = ({

const boundaries = rowsVisibleBoundary || [0, rows.length - 1 || 1];

const getSpanBoundaryByRow = (row: TableRow) => getSpanBoundary(
columns,
columnsVisibleBoundary,
column => getColSpan(row, column),
);

const rowSpanBoundaries = rows
.slice(boundaries[0], boundaries[1])
.map(row => getSpanBoundary(
columns,
columnsVisibleBoundary,
column => getColSpan(row, column),
));
.slice(boundaries[0], boundaries[1] + 1)
.map(row => getSpanBoundaryByRow(row));
const columnBoundaries = collapseBoundaries(
columns.length,
columnsVisibleBoundary,
Expand All @@ -301,11 +318,7 @@ export const getCollapsedGrid: GetCollapsedGridFn = ({
getRowHeight,
row => getCollapsedCells(
columns,
getSpanBoundary(
columns,
columnsVisibleBoundary,
column => getColSpan(row, column),
),
getSpanBoundaryByRow(row),
columnBoundaries,
column => getColSpan(row, column),
),
Expand Down Expand Up @@ -361,7 +374,7 @@ export const getCollapsedGrids: GetCollapsedGridsFn = ({
});

const headerGrid = getCollapsedGridBlock(
headerRows, getRenderRowBounds(viewport.headerRows, headerRows.length),
headerRows, getRowsRenderBoundary(headerRows.length, viewport.headerRows),
);
const bodyGrid = getCollapsedGridBlock(
bodyRows,
Expand All @@ -371,8 +384,9 @@ export const getCollapsedGrids: GetCollapsedGridsFn = ({
totalRowCount || 1,
loadedRowsStart,
);

const footerGrid = getCollapsedGridBlock(
footerRows, getRenderRowBounds(viewport.footerRows, footerRows.length),
footerRows, getRowsRenderBoundary(footerRows.length, viewport.footerRows),
);

return {
Expand All @@ -382,18 +396,11 @@ export const getCollapsedGrids: GetCollapsedGridsFn = ({
};
};

const getRenderRowBounds: PureComputed<[VisibleBoundary, number], number[]> = (
visibleBounds, rowCount,
) => getRowsRenderBoundary(
rowCount,
visibleBounds,
);

const adjustedRenderRowBounds: PureComputed<[VisibleBoundary, number, number], number[]> = (
visibleBounds, rowCount, loadedRowsStart,
) => {
const renderRowBoundaries = getRenderRowBounds(
visibleBounds, loadedRowsStart + rowCount,
const renderRowBoundaries = getRowsRenderBoundary(
loadedRowsStart + rowCount, visibleBounds,
);
const adjustedInterval = intervalUtil.intersect(
{ start: renderRowBoundaries[0], end: renderRowBoundaries[1] },
Expand Down

0 comments on commit b7c3919

Please sign in to comment.