Skip to content

Commit

Permalink
feat: add grouped table (#408)
Browse files Browse the repository at this point in the history
* feat: add grouped table

* fix: fix types

* fix: revert table default story & fix typing

* fix: delete flow fixme comment
  • Loading branch information
ShtykovAlexander authored Mar 28, 2022
1 parent b752cfd commit d3462be
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 4 deletions.
97 changes: 97 additions & 0 deletions src/components/Table/Table.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,81 @@ const TABLE_DATA = [
},
];

const GROUPED_TABLE_DATA = [
{
id: '1',
group: 'First',
createdAt: '2018-09-03T09:59:43.000Z',
updatedAt: '2018-09-03T09:59:43.000Z',
firstName: 'Cecily',
lastName: 'Oen',
email: '[email protected]',
},
{
id: '2',
group: 'First',
createdAt: '2018-09-03T10:34:15.000Z',
updatedAt: '2018-09-03T10:34:15.000Z',
firstName: 'Larry',
lastName: 'Marwick',
email: '[email protected]',
},
{
id: '3',
group: 'First',
createdAt: '2018-09-03T09:59:46.000Z',
updatedAt: '2018-09-03T09:59:46.000Z',
firstName: 'Evangelina',
lastName: 'Korner',
email: '[email protected]',
},
{
id: '4',
group: 'Second',
createdAt: '2018-09-03T09:59:43.000Z',
updatedAt: '2018-09-03T09:59:43.000Z',
firstName: 'Dian',
lastName: 'Wegge',
email: '[email protected]',
},
{
id: '5',
group: 'Second',
createdAt: '2018-09-03T09:59:45.000Z',
updatedAt: '2018-09-03T09:59:45.000Z',
firstName: 'Chas',
lastName: 'Dalrymple',
email: '[email protected]',
},
{
id: '6',
group: 'Third',
createdAt: '2018-09-03T09:59:43.000Z',
updatedAt: '2018-09-03T09:59:43.000Z',
firstName: 'Preston',
lastName: 'Bonini',
email: '[email protected]',
},
{
id: '7',
group: 'Third',
createdAt: '2018-09-03T09:59:45.000Z',
updatedAt: '2018-09-03T09:59:45.000Z',
firstName: 'Chas',
lastName: 'Dalrymple',
email: '[email protected]',
},
{
id: '8',
group: 'First',
createdAt: '2018-09-03T09:59:45.000Z',
updatedAt: '2018-09-03T09:59:45.000Z',
firstName: 'Chas',
lastName: 'Dalrymple',
email: '[email protected]',
},
];

const fetchData = async (page, pageSize) => {
await (() => new Promise(resolve => setTimeout(resolve, 5000)))();

Expand Down Expand Up @@ -418,6 +493,28 @@ defaultStory.story = {
name: 'default',
};

export const grouped = () => (
<div style={{ display: 'flex', height: '600px' }}>
<TableBuilder
columns={ TABLE_COLUMNS }
data={ GROUPED_TABLE_DATA }
groupBy={ (data) =>
data.reduce(
(acc, item) => {
if (!acc[item.group]) {
return { ...acc, [item.group]: [item] };
}
acc[item.group] = [...acc[item.group], item];
return acc;
}, {}) }
/>
</div>
);

grouped.story = {
name: 'grouped',
};

export const withLoader = () => (
<div style={{ display: 'flex', height: '600px' }}>
<Table>
Expand Down
3 changes: 3 additions & 0 deletions src/components/Table/TableBodyRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ const [TableBodyRowTag, theme] = createThemeTag(name, ({ COLORS }: *) => ({
borderLeft: `1px solid ${COLORS.SECONDARY_BORDER_COLOR}`,
borderRight: `1px solid ${COLORS.SECONDARY_BORDER_COLOR}`,
},
borderedLess: {
border: 'none',
},
},
}));

Expand Down
40 changes: 36 additions & 4 deletions src/components/Table/TableBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import { TableHeaderCell } from './TableHeaderCell';
import { Table } from './Table';
import { Checkbox } from '../Checkbox';
import { Pagination } from '../Pagination';
import { TableBodyRow } from './TableBodyRow';
import { TableBodyCell } from './TableBodyCell';
import { Heading } from '../Heading';

const DEFAULT_SORT_ENABLE = true;

Expand Down Expand Up @@ -63,7 +66,7 @@ type TableBulderProps = {
withPagination?: boolean,
/** Options to show loader */
loading?: boolean,
/** Calback to render cell */
/** Callback to render cell */
renderCell?: (column: ColumnType, data: any, opts: { expandRow: () => void, isExpanded?: boolean }) => React$Node,
/** Callback to render head cell */
renderHeadCell?: (column: ColumnType) => React$Node,
Expand All @@ -77,6 +80,10 @@ type TableBulderProps = {
expandedRowRender?: (data: ExpandedRowRenderData) => React$Node,
/** Callback executed when the row `isExpanded` state is changed */
onExpand?: ({ key: string, isExpanded: boolean }) => void,
/** Callback to group data by field*/
groupBy: <T: $Shape<any>>(data: T[]) => { [key: string]: T[]},
/** Callback to render grouped table title */
renderGroupTitle?: (key: string, data: Array<Object>) => React$Node,
};

type TableBuilderState = {|
Expand Down Expand Up @@ -315,12 +322,11 @@ class TableBuilder extends PureComponent<TableBulderProps, TableBuilderState> {
);
}

renderBody = () => {
renderBody = (data: Array<Object>) => {
const {
columns,
onActionClick,
action,
data,
withSelection,
renderCell,
noData,
Expand Down Expand Up @@ -364,6 +370,32 @@ class TableBuilder extends PureComponent<TableBulderProps, TableBuilderState> {
);
}

renderContent = () => {
const { groupBy, data, renderGroupTitle } = this.props;

if (groupBy && typeof groupBy === 'function') {

const groupedData = groupBy(data) || {};
return (
<div style={{ overflow: 'auto' }}>
{ Object.keys(groupedData).map((key) => (
<div key={ key }>
{ renderGroupTitle && typeof renderGroupTitle === 'function' ?
renderGroupTitle(key, groupedData[key]) :
<TableBodyRow borderedLess>
<TableBodyCell>
<Heading type="h4">{ key }</Heading>
</TableBodyCell>
</TableBodyRow> }
{ this.renderBody(groupedData[key]) }
</div>
)) }
</div>);
}

return this.renderBody(data);
};

onChangePagination = (page: number, pageSize: number) => {
const { onChange, tableState } = this.props;

Expand Down Expand Up @@ -404,7 +436,7 @@ class TableBuilder extends PureComponent<TableBulderProps, TableBuilderState> {
return (
<Table modifiers={ rest }>
{ this.renderHeader() }
{ this.renderBody() }
{ this.renderContent() }
{ this.renderFooter() }
</Table>
);
Expand Down

0 comments on commit d3462be

Please sign in to comment.