Skip to content

Commit

Permalink
fix(react-grid): fix grouping if TableGroupRow is placed before any o…
Browse files Browse the repository at this point in the history
…ther table plugin (#218)
  • Loading branch information
kvet authored Jul 25, 2017
1 parent 7d46d17 commit 7e09c7e
Show file tree
Hide file tree
Showing 16 changed files with 211 additions and 87 deletions.
2 changes: 1 addition & 1 deletion packages/dx-grid-core/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export * from './plugins/table-selection/computeds';
export {
tableRowKeyGetter,
tableColumnKeyGetter,
getTableCellInfo,
getTableRowColumnsWithColSpan,
findTableCellTarget,
getTableColumnGeometries,
getTableTargetColumnIndex,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ const groupRows = (originalRows, groupedColumns, parentGroup) => {
group = {
_headerKey: `groupRow_${groupColumn.name}`,
key: (parentGroup ? `${parentGroup.key}${SEPARATOR}` : '') + groupKey,
colspan: (parentGroup ? parentGroup.colspan + 1 : 0),
value: groupKey,
type: 'groupRow',
column: groupColumn,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ describe('GroupingPlugin computeds', () => {
value: '1',
type: 'groupRow',
column: { name: 'a' },
colspan: 0,
});
expect(grouped[0].rows).toHaveLength(2);
expect(grouped[0].rows[0]).toMatchObject(rows[0]);
Expand All @@ -39,7 +38,6 @@ describe('GroupingPlugin computeds', () => {
value: '2',
type: 'groupRow',
column: { name: 'a' },
colspan: 0,
});
expect(grouped[1].rows).toHaveLength(2);
expect(grouped[1].rows[0]).toMatchObject(rows[2]);
Expand All @@ -56,22 +54,19 @@ describe('GroupingPlugin computeds', () => {
value: '1',
type: 'groupRow',
column: { name: 'a' },
colspan: 0,
});
expect(grouped[0].rows).toHaveLength(2);
expect(grouped[0].rows[0]).toMatchObject({
key: '1|1',
value: '1',
type: 'groupRow',
column: { name: 'b' },
colspan: 1,
});
expect(grouped[0].rows[1]).toMatchObject({
key: '1|2',
value: '2',
type: 'groupRow',
column: { name: 'b' },
colspan: 1,
});
expect(grouped[0].rows[0].rows).toHaveLength(1);
expect(grouped[0].rows[1].rows).toHaveLength(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ const tableColumnsWithDraftGrouping = (columns, grouping) => columns.reduce((acc

export const tableColumnsWithGrouping = (columns, grouping,
draftGrouping, groupIndentColumnWidth) => [
...grouping.map(group => ({ type: 'groupColumn', group, width: groupIndentColumnWidth })),
...grouping.map(group =>
({ type: 'groupColumn', id: group.columnName, group, width: groupIndentColumnWidth })),
...tableColumnsWithDraftGrouping(columns, draftGrouping),
];

export const tableRowsWithGrouping = rows =>
rows.map((row) => {
if (row.type !== 'groupRow') return row;
return { ...row, colSpanStart: `groupColumn_${row.column.name}` };
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { tableColumnsWithGrouping } from './computeds';
import {
tableColumnsWithGrouping,
tableRowsWithGrouping,
} from './computeds';

describe('TableGroupRow Plugin computeds', () => {
describe('#tableColumnsWithGrouping', () => {
Expand All @@ -19,11 +22,13 @@ describe('TableGroupRow Plugin computeds', () => {
expect(columns).toHaveLength(6);
expect(columns[0]).toMatchObject({
type: 'groupColumn',
id: 'a',
group: { columnName: 'a' },
width: 123,
});
expect(columns[1]).toMatchObject({
type: 'groupColumn',
id: 'c',
group: { columnName: 'c' },
width: 123,
});
Expand Down Expand Up @@ -77,4 +82,19 @@ describe('TableGroupRow Plugin computeds', () => {
expect(columns[1]).toBe(allColumns[3]);
});
});
describe('#tableRowsWithGrouping', () => {
it('should add correct colSpanStart to group rows', () => {
const rows = [
{ type: 'groupRow', column: { name: 'a' } },
{},
{},
];

expect(tableRowsWithGrouping(rows))
.toEqual([
{ type: 'groupRow', column: { name: 'a' }, colSpanStart: 'groupColumn_a' },
...rows.slice(1),
]);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const expandedDetailRows = (sourceRows, expandedRows, getRowId, rowHeight
const row = rows[rowIndex];
rows = [
...rows.slice(0, insertIndex),
{ type: 'detailRow', id: getRowId(row), for: row, colspan: 0, height: rowHeight },
{ type: 'detailRow', id: getRowId(row), for: row, colSpanStart: 0, height: rowHeight },
...rows.slice(insertIndex),
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('DetailRow computeds', () => {
type: 'detailRow',
id: 2,
for: { id: 2 },
colspan: 0,
colSpanStart: 0,
height: 'auto',
},
]);
Expand All @@ -34,15 +34,15 @@ describe('DetailRow computeds', () => {
type: 'detailRow',
id: 1,
for: { id: 1 },
colspan: 0,
colSpanStart: 0,
height: 'auto',
},
{ id: 2 },
{
type: 'detailRow',
id: 2,
for: { id: 2 },
colspan: 0,
colSpanStart: 0,
height: 'auto',
},
]);
Expand Down
18 changes: 14 additions & 4 deletions packages/dx-grid-core/src/utils/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,20 @@ const getColumnId = column => column.name;
export const tableColumnKeyGetter = (column, columnIndex) =>
getTableKeyGetter(getColumnId, column, columnIndex);

export const getTableCellInfo = ({ row, columnIndex, columns }) => {
if (row.colspan !== undefined && columnIndex > row.colspan) return { skip: true };
if (row.colspan === columnIndex) return { colspan: columns.length - row.colspan };
return {};
export const getTableRowColumnsWithColSpan = (columns, colSpanStart) => {
if (colSpanStart === undefined) return columns.map(column => ({ original: column }));

let span = false;
return columns
.reduce((acc, column, columnIndex) => {
if (span) return acc;
if (columnIndex === colSpanStart ||
tableColumnKeyGetter(column, columnIndex) === colSpanStart) {
span = true;
return [...acc, { original: column, colspan: columns.length - columnIndex }];
}
return [...acc, { original: column }];
}, []);
};

export const findTableCellTarget = (e) => {
Expand Down
30 changes: 30 additions & 0 deletions packages/dx-grid-core/src/utils/table.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
tableRowKeyGetter,
getTableColumnGeometries,
getTableTargetColumnIndex,
getTableRowColumnsWithColSpan,
} from './table';

describe('table utils', () => {
Expand Down Expand Up @@ -35,6 +36,35 @@ describe('table utils', () => {
});
});

describe('#getTableRowColumnsWithColSpan', () => {
it('should return correct columns without colspan', () => {
const columns = [{ type: 'a', id: 1 }, { type: 'b', id: 2 }];

expect(getTableRowColumnsWithColSpan(columns, {}))
.toEqual(columns.map(column => ({ original: column })));
});

it('should return correct columns with numeric colspan', () => {
const columns = [{ type: 'a', id: 1 }, { type: 'b', id: 2 }, { type: 'c', id: 3 }];

expect(getTableRowColumnsWithColSpan(columns, 0))
.toEqual([{ original: columns[0], colspan: 3 }]);

expect(getTableRowColumnsWithColSpan(columns, 1))
.toEqual([{ original: columns[0] }, { original: columns[1], colspan: 2 }]);
});

it('should return correct columns with string colspan', () => {
const columns = [{ type: 'a', id: 1 }, { type: 'b', id: 2 }, { type: 'c', id: 3 }];

expect(getTableRowColumnsWithColSpan(columns, 'a_1'))
.toEqual([{ original: columns[0], colspan: 3 }]);

expect(getTableRowColumnsWithColSpan(columns, 'b_2'))
.toEqual([{ original: columns[0] }, { original: columns[1], colspan: 2 }]);
});
});

describe('#getTableColumnGeometries', () => {
it('should correctly return geometries', () => {
const columns = [{ width: 100 }, {}, {}];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import React from 'react';
import PropTypes from 'prop-types';
import { getTableRowColumnsWithColSpan } from '@devexpress/dx-grid-core';
import { WindowedScroller } from './virtual-table/windowed-scroller';
import { VirtualBox } from './virtual-table/virtual-box';

Expand Down Expand Up @@ -49,20 +50,20 @@ export class VirtualTable extends React.Component {
const scrollWidth = columnWidths.reduce((accum, width) => accum + width, 0);

const tableRow = (row, position) => {
const colspan = row.colspan;
const columnLength = colspan !== undefined ? colspan + 1 : columns.length;
const columnsWithColSpan = getTableRowColumnsWithColSpan(columns, row.colSpanStart);
return (
<VirtualBox
rootTag="tr"

position={position}
crossSize={this.rowHeight(row)}
direction="horizontal"
itemCount={columnLength}
itemCount={columnsWithColSpan.length}
itemInfo={(columnIndex) => {
const size = columnIndex !== colspan
const columnWithColSpan = columnsWithColSpan[columnIndex];
const size = !columnWithColSpan.colspan
? columnWidths[columnIndex]
: columns.slice(colspan).reduce(
: columns.slice(columnIndex).reduce(
(accum, column) => accum + columnWidths[columns.indexOf(column)],
0,
);
Expand All @@ -73,7 +74,7 @@ export class VirtualTable extends React.Component {
};
}}
itemTemplate={(columnIndex, _, style) =>
cellTemplate({ row, column: columns[columnIndex], style })}
cellTemplate({ row, column: columnsWithColSpan[columnIndex].original, style })}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ describe('TableLayout', () => {
});

it('should span columns if specified', () => {
const rows = [{ id: 1, colspan: 0 }, { id: 2, colspan: 1 }];
const rows = [{ id: 1, colSpanStart: 0 }, { id: 2, colSpanStart: 1 }];
const columns = [{ name: 'a' }, { name: 'b' }, { name: 'c' }, { name: 'd' }];
const tree = mount(
<TableLayout
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {

import {
tableColumnKeyGetter,
getTableCellInfo,
getTableRowColumnsWithColSpan,
} from '@devexpress/dx-grid-core';

const getColumnStyle = ({ column, animationState = {} }) => ({
Expand Down Expand Up @@ -36,11 +36,9 @@ export class RowLayout extends React.PureComponent {
style={getRowStyle({ row })}
>
{
columns
.filter((column, columnIndex) => !getTableCellInfo({ row, columns, columnIndex }).skip)
.map((column, columnIndex) => {
getTableRowColumnsWithColSpan(columns, row.colSpanStart)
.map(({ original: column, colspan }, columnIndex) => {
const key = tableColumnKeyGetter(column, columnIndex);
const colspan = getTableCellInfo({ row, columns, columnIndex }).colspan;
return (
<TemplateRenderer
key={key}
Expand Down
12 changes: 11 additions & 1 deletion packages/dx-react-grid/src/plugins/table-group-row.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Getter, Template, PluginContainer } from '@devexpress/dx-react-core';
import { tableColumnsWithGrouping } from '@devexpress/dx-grid-core';
import {
tableColumnsWithGrouping,
tableRowsWithGrouping,
} from '@devexpress/dx-grid-core';

export class TableGroupRow extends React.PureComponent {
render() {
Expand All @@ -23,6 +26,13 @@ export class TableGroupRow extends React.PureComponent {
groupIndentColumnWidth,
]}
/>
<Getter
name="tableBodyRows"
pureComputed={tableRowsWithGrouping}
connectArgs={getter => [
getter('tableBodyRows'),
]}
/>

<Template
name="tableViewCell"
Expand Down
Loading

0 comments on commit 7e09c7e

Please sign in to comment.