Skip to content

Commit

Permalink
feat(Table): Support local filters on columns (#314)
Browse files Browse the repository at this point in the history
* feat: Add filter to Table (#270)

* feat: Add filter to Table

* feat: Table filtering improvements

* fix: Table storybook

* feat: Improve SelectColumnFilter styles

* feat: Add test for filtering table

* fix: Lint table test file

* feat: Add disableFilters for table filter story

* fix: Add Stack for vertical spacing

* fix: New property to control column filter

* fix: Update table story

* fix: column filter table test

* fix: table lint

* chore: Minor update on the docs

* chore: Use search type input

* chore: Fix the issue the column filters are all on when the global filter is used

Co-authored-by: Maksim Markelov <[email protected]>
  • Loading branch information
jessieweiyi and mmarkelov authored Aug 23, 2021
1 parent cbda94f commit 7d43b42
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 22 deletions.
39 changes: 39 additions & 0 deletions src/components/Table/components/DefaultColumnFilter/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/** *******************************************************************************************************************
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. *
******************************************************************************************************************** */
import React from 'react';
import Input from '../../../Input';
import { UseFiltersColumnProps } from 'react-table';

interface Props<D extends object> {
column: UseFiltersColumnProps<D>;
}

export default function DefaultColumnFilter<D extends object>({
column: { filterValue, preFilteredRows, setFilter },
}: Props<D>) {
const count = preFilteredRows.length;

return (
<Input
value={filterValue || ''}
onChange={(e) => {
setFilter(e || undefined);
}}
type="search"
placeholder={`Search ${count} records...`}
/>
);
}
21 changes: 17 additions & 4 deletions src/components/Table/components/TableHead/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,16 @@
import React from 'react';

import { TableHead as BaseTableHead, TableCell, TableRow, TableSortLabel } from '@material-ui/core';
import { Column, ColumnInstance, HeaderGroup, UseSortByColumnProps, UseResizeColumnsColumnProps } from 'react-table';
import {
Column,
ColumnInstance,
HeaderGroup,
UseSortByColumnProps,
UseResizeColumnsColumnProps,
UseFiltersColumnProps,
} from 'react-table';
import ArrowDropDown from '@material-ui/icons/ArrowDropDown';
import { Stack } from '../../../../layouts';

export interface TableHeadProps<D extends object> {
headerGroups: HeaderGroup<D>[];
Expand All @@ -37,12 +45,16 @@ export default function TableHead<D extends object>({ headerGroups, styles }: Ta
{headerGroup.headers.map(
(
column: Partial<
ColumnInstance<D> & Column<D> & UseSortByColumnProps<D> & UseResizeColumnsColumnProps<D>
ColumnInstance<D> &
Column<D> &
UseSortByColumnProps<D> &
UseResizeColumnsColumnProps<D> &
UseFiltersColumnProps<D>
>
) =>
column.id !== '_all_' && (
<TableCell {...column.getHeaderProps!()}>
<div>
<Stack spacing="xs">
{column.canSort ? (
<TableSortLabel
{...column.getSortByToggleProps!()}
Expand All @@ -56,8 +68,9 @@ export default function TableHead<D extends object>({ headerGroups, styles }: Ta
) : (
<span>{column.render?.('Header')}</span>
)}
<div>{column.canFilter ? column.render?.('Filter') : null}</div>
<div {...column.getResizerProps!()} className={styles.resizer} />
</div>
</Stack>
</TableCell>
)
)}
Expand Down
85 changes: 85 additions & 0 deletions src/components/Table/data/filterColumnDefinitions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/** *******************************************************************************************************************
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. *
******************************************************************************************************************** */
import React from 'react';
import { DataType } from './type';
import { Column } from '../';
import Select from '../../Select';
import { Button } from '../../index';
import { Inline } from '../../../layouts';

function SelectColumnFilter({ column: { filterValue, setFilter } }: any) {
const options = [
{
label: 'Order 11',
value: 'Order 11',
},
{
label: 'Order 12',
value: 'Order 12',
},
{
label: 'Order 13',
value: 'Order 13',
},
];

return (
<Inline spacing="xs">
<Select
options={options}
selectedOption={options.find(({ value }) => value === filterValue)}
onChange={(e) => {
setFilter(e.target.value || undefined);
}}
/>
<Button onClick={() => setFilter(undefined)} size="small">
Clear
</Button>
</Inline>
);
}

const filterColumnDefinition: Column<DataType>[] = [
{
id: 'id',
width: 200,
Header: 'Id',
accessor: 'id',
},
{
id: 'name',
width: 200,
Header: 'Name',
Filter: SelectColumnFilter,
accessor: 'name',
},
{
id: 'createdDate',
width: 200,
Header: 'Created date',
accessor: 'createdDate',
},
{
id: 'accounts',
width: 200,
Header: '# Accounts',
disableFilters: true,
disableGlobalFilter: true,
accessor: (row) => row.accounts?.length,
},
];

export default filterColumnDefinition;
3 changes: 2 additions & 1 deletion src/components/Table/data/groupBy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
See the License for the specific language governing permissions and
limitations under the License. *
******************************************************************************************************************** */
import { DataType } from './type';

const data = [
const data: DataType[] = [
{
id: 'id0000011',
name: 'Order 11',
Expand Down
3 changes: 2 additions & 1 deletion src/components/Table/data/long.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
See the License for the specific language governing permissions and
limitations under the License. *
******************************************************************************************************************** */
import { DataType } from './type';

const data = [
const data: DataType[] = [
{
id: 'id0000011',
name: 'Order 11',
Expand Down
3 changes: 2 additions & 1 deletion src/components/Table/data/short.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
See the License for the specific language governing permissions and
limitations under the License. *
******************************************************************************************************************** */
import { DataType } from './type';

const data = [
const data: DataType[] = [
{
id: 'id0000011',
name: 'Order 11',
Expand Down
22 changes: 15 additions & 7 deletions src/components/Table/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import groupByData from './data/groupBy';
import { DataType } from './data/type';
import columnDefinitions from './data/columnDefinitions';
import orderBy from 'lodash.orderby';
import filterColumnDefinition from './data/filterColumnDefinitions';

export default {
component: Table,
Expand Down Expand Up @@ -118,6 +119,16 @@ export const GroupBy = () => (
/>
);

export const ColumnFilters = () => (
<Table
tableTitle={'Column Filter Table'}
columnDefinitions={filterColumnDefinition}
items={groupByData}
disableRowSelect={false}
disableColumnFilters={false}
/>
);

export const Complex = () => (
<Table
onSelectionChange={action('onSelectionChange')}
Expand Down Expand Up @@ -160,17 +171,13 @@ export const WithActionGroup = () => {
);
};

interface Data {
id: string;
name: string;
}

export const RemoteFetch = () => {
const [items, setItems] = useState<Data[]>([]);
const [items, setItems] = useState<DataType[]>([]);
const [rowCount, setRowCount] = useState(0);
const [loading, setLoading] = useState(false);
const fetchIdRef = React.useRef(0);
const data = useMemo<Data[]>(() => {
const getRowId = useCallback((data) => data.id, []);
const data = useMemo<DataType[]>(() => {
const data = [];
for (let i = 0; i < 1000; i++) {
data.push({
Expand Down Expand Up @@ -219,6 +226,7 @@ export const RemoteFetch = () => {
rowCount={rowCount}
items={items}
loading={loading}
getRowId={getRowId}
onSelectionChange={action('onSelectionChange')}
/>
);
Expand Down
14 changes: 14 additions & 0 deletions src/components/Table/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,18 @@ describe('Table', () => {

expect(getAllByRole('rowgroup')[1].childNodes).toHaveLength(5);
});

it('should render filter', () => {
const { getAllByPlaceholderText } = render(
<Table
tableTitle={'My Table'}
columnDefinitions={columnDefinitions}
items={dataGroup}
disableRowSelect={true}
disableColumnFilters={false}
/>
);

expect(getAllByPlaceholderText('Search 10 records...')).toHaveLength(2);
});
});
Loading

0 comments on commit 7d43b42

Please sign in to comment.