-
Notifications
You must be signed in to change notification settings - Fork 380
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(react-grid): support custom grouping processing (#395)
- Loading branch information
Showing
35 changed files
with
1,343 additions
and
291 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
packages/dx-grid-core/src/plugins/custom-grouping/computeds.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { | ||
GROUP_KEY_SEPARATOR, | ||
} from '../grouping-state/constants'; | ||
import { | ||
GRID_GROUP_TYPE, | ||
GRID_GROUP_CHECK, | ||
GRID_GROUP_LEVEL_KEY, | ||
} from '../local-grouping/constants'; | ||
|
||
export const customGroupedRows = ( | ||
currentRows, | ||
grouping, | ||
getChildGroups, | ||
rootRows = currentRows, | ||
keyPrefix = '', | ||
) => { | ||
if (!currentRows) return []; | ||
if (!grouping.length) return currentRows; | ||
|
||
const groupedBy = grouping[0].columnName; | ||
const nestedGrouping = grouping.slice(1); | ||
return getChildGroups(currentRows, grouping[0], rootRows) | ||
.reduce((acc, { key, value = key, childRows }) => { | ||
const compoundKey = `${keyPrefix}${key}`; | ||
acc.push({ | ||
[GRID_GROUP_CHECK]: true, | ||
[GRID_GROUP_LEVEL_KEY]: `${GRID_GROUP_TYPE}_${groupedBy}`, | ||
groupedBy, | ||
compoundKey, | ||
key, | ||
value, | ||
}); | ||
acc.push(...customGroupedRows( | ||
childRows, | ||
nestedGrouping, | ||
getChildGroups, | ||
rootRows, | ||
`${compoundKey}${GROUP_KEY_SEPARATOR}`, | ||
)); | ||
return acc; | ||
}, []); | ||
}; | ||
|
||
export const customGroupingRowIdGetter = (getRowId, rows) => { | ||
const firstRow = rows.find(row => !row[GRID_GROUP_CHECK]); | ||
if (!firstRow || getRowId(firstRow)) { | ||
return getRowId; | ||
} | ||
const map = new Map(rows | ||
.filter(row => !row[GRID_GROUP_CHECK]) | ||
.map((row, rowIndex) => [row, rowIndex])); | ||
|
||
return row => map.get(row); | ||
}; |
232 changes: 232 additions & 0 deletions
232
packages/dx-grid-core/src/plugins/custom-grouping/computeds.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
import { | ||
customGroupedRows, | ||
customGroupingRowIdGetter, | ||
} from './computeds'; | ||
import { | ||
GRID_GROUP_TYPE, | ||
GRID_GROUP_CHECK, | ||
GRID_GROUP_LEVEL_KEY, | ||
} from '../local-grouping/constants'; | ||
|
||
describe('CustomGrouping Plugin computeds', () => { | ||
const groupRow = ({ groupedBy, ...restParams }) => ({ | ||
...restParams, | ||
groupedBy, | ||
[GRID_GROUP_CHECK]: true, | ||
[GRID_GROUP_LEVEL_KEY]: `${GRID_GROUP_TYPE}_${groupedBy}`, | ||
}); | ||
|
||
describe('#customGroupedRows', () => { | ||
it('should process hierarchical data by one column', () => { | ||
const hierarchicalSource = [{ | ||
key: 1, | ||
items: [ | ||
{ a: 1, b: 1 }, | ||
{ a: 1, b: 2 }, | ||
], | ||
}, { | ||
key: 2, | ||
items: [ | ||
{ a: 2, b: 1 }, | ||
{ a: 2, b: 2 }, | ||
], | ||
}]; | ||
const getHierarchicalChildGroups = groups => groups | ||
.map(group => ({ key: String(group.key), value: group.key, childRows: group.items })); | ||
const groupings = [{ columnName: 'a' }]; | ||
const groupedRows = [ | ||
groupRow({ | ||
groupedBy: 'a', | ||
compoundKey: '1', | ||
key: '1', | ||
value: 1, | ||
}), | ||
{ a: 1, b: 1 }, | ||
{ a: 1, b: 2 }, | ||
groupRow({ | ||
groupedBy: 'a', | ||
compoundKey: '2', | ||
key: '2', | ||
value: 2, | ||
}), | ||
{ a: 2, b: 1 }, | ||
{ a: 2, b: 2 }, | ||
]; | ||
|
||
const getChildGroups = jest.fn(getHierarchicalChildGroups); | ||
|
||
expect(customGroupedRows( | ||
hierarchicalSource, | ||
groupings, | ||
getChildGroups, | ||
)) | ||
.toEqual(groupedRows); | ||
|
||
expect(getChildGroups) | ||
.toBeCalledWith(hierarchicalSource, groupings[0], hierarchicalSource); | ||
}); | ||
|
||
it('should process hierarchical data by one column with remote expanded groups', () => { | ||
const hierarchicalSource = [{ | ||
key: 1, | ||
items: null, | ||
}]; | ||
const getHierarchicalChildGroups = groups => groups | ||
.map(group => ({ key: String(group.key), value: group.key, childRows: group.items })); | ||
const groupings = [{ columnName: 'a' }]; | ||
const groupedRows = [ | ||
groupRow({ | ||
groupedBy: 'a', | ||
compoundKey: '1', | ||
key: '1', | ||
value: 1, | ||
}), | ||
]; | ||
|
||
const getChildGroups = jest.fn(getHierarchicalChildGroups); | ||
|
||
expect(customGroupedRows( | ||
hierarchicalSource, | ||
groupings, | ||
getChildGroups, | ||
)) | ||
.toEqual(groupedRows); | ||
}); | ||
|
||
it('should process hierarchical data by several columns', () => { | ||
const hierarchicalSource = [{ | ||
key: 1, | ||
items: [{ | ||
key: 1, | ||
items: [ | ||
{ a: 1, b: 1 }, | ||
], | ||
}, { | ||
key: 2, | ||
items: [ | ||
{ a: 1, b: 2 }, | ||
], | ||
}], | ||
}, { | ||
key: 2, | ||
items: [{ | ||
key: 1, | ||
items: [ | ||
{ a: 2, b: 1 }, | ||
], | ||
}, { | ||
key: 2, | ||
items: [ | ||
{ a: 2, b: 2 }, | ||
], | ||
}], | ||
}]; | ||
const getHierarchicalChildGroups = groups => groups | ||
.map(group => ({ key: String(group.key), value: group.key, childRows: group.items })); | ||
const groupings = [{ columnName: 'a' }, { columnName: 'b' }]; | ||
const groupedRows = [ | ||
groupRow({ | ||
groupedBy: 'a', | ||
compoundKey: '1', | ||
key: '1', | ||
value: 1, | ||
}), | ||
groupRow({ | ||
groupedBy: 'b', | ||
compoundKey: '1|1', | ||
key: '1', | ||
value: 1, | ||
}), | ||
{ a: 1, b: 1 }, | ||
groupRow({ | ||
groupedBy: 'b', | ||
compoundKey: '1|2', | ||
key: '2', | ||
value: 2, | ||
}), | ||
{ a: 1, b: 2 }, | ||
groupRow({ | ||
groupedBy: 'a', | ||
compoundKey: '2', | ||
key: '2', | ||
value: 2, | ||
}), | ||
groupRow({ | ||
groupedBy: 'b', | ||
compoundKey: '2|1', | ||
key: '1', | ||
value: 1, | ||
}), | ||
{ a: 2, b: 1 }, | ||
groupRow({ | ||
groupedBy: 'b', | ||
compoundKey: '2|2', | ||
key: '2', | ||
value: 2, | ||
}), | ||
{ a: 2, b: 2 }, | ||
]; | ||
|
||
const getChildGroups = jest.fn(getHierarchicalChildGroups); | ||
|
||
expect(customGroupedRows( | ||
hierarchicalSource, | ||
groupings, | ||
getChildGroups, | ||
)) | ||
.toEqual(groupedRows); | ||
|
||
expect(getChildGroups) | ||
.toBeCalledWith(hierarchicalSource, groupings[0], hierarchicalSource); | ||
expect(getChildGroups) | ||
.toBeCalledWith(hierarchicalSource[0].items, groupings[1], hierarchicalSource); | ||
expect(getChildGroups) | ||
.toBeCalledWith(hierarchicalSource[1].items, groupings[1], hierarchicalSource); | ||
}); | ||
}); | ||
|
||
describe('#customGroupingRowIdGetter', () => { | ||
it('should define row ids to rows if not present', () => { | ||
const groupedRows = [ | ||
groupRow({ | ||
groupedBy: 'a', | ||
key: '1', | ||
value: 1, | ||
}), | ||
{ a: 1, b: 1 }, | ||
{ a: 1, b: 2 }, | ||
]; | ||
const parentGetRowId = () => undefined; | ||
const getRowId = customGroupingRowIdGetter(parentGetRowId, groupedRows); | ||
|
||
expect(getRowId(groupedRows[1])) | ||
.toBe(0); | ||
expect(getRowId(groupedRows[2])) | ||
.toBe(1); | ||
}); | ||
|
||
it('should not define row ids to empty rows', () => { | ||
const parentGetRowId = () => undefined; | ||
const getRowId = customGroupingRowIdGetter(parentGetRowId, [], []); | ||
|
||
expect(getRowId(1)) | ||
.toBe(undefined); | ||
}); | ||
|
||
it('should not define row ids if getRowId is defined', () => { | ||
const groupedRows = [ | ||
groupRow({ | ||
groupedBy: 'a', | ||
key: '1', | ||
value: 1, | ||
}), | ||
{ a: 1, b: 1 }, | ||
]; | ||
const parentGetRowId = () => 1; | ||
const getRowId = customGroupingRowIdGetter(parentGetRowId, groupedRows); | ||
|
||
expect(getRowId(1)) | ||
.toBe(1); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.