Skip to content

Commit

Permalink
feat: update to match changes to react-table
Browse files Browse the repository at this point in the history
Signed-off-by: Mike Murray <[email protected]>
  • Loading branch information
mikemurray committed Jan 17, 2020
1 parent 9580bd9 commit 5062aa8
Showing 1 changed file with 96 additions and 140 deletions.
236 changes: 96 additions & 140 deletions package/src/components/DataTable/helpers/useDataTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { Checkbox } from "@material-ui/core";
import {
useTable,
useFilters,
useTableState,
usePagination,
useRowSelect
useRowSelect,
useGlobalFilter
} from "react-table";
import useDataTableCellProps from "./useDataTableCellProps";

Expand All @@ -16,30 +16,20 @@ import useDataTableCellProps from "./useDataTableCellProps";
*/
export default function useDataTable({
DefaultColumnFilter,
data: simpleData,
columns,
data,
getRowId,
pageCount: controlledPageCount,
onFetchData,
onSelectRows,
onRowClick,
onGlobalFilterChange,
pageSize: defaultPageSize = 10,
onRowSelect,
disableRowClick = false,
disableRowSelect = false,
...otherProps
}) {
const [stateData, setData] = useState([]);
const [pageCount, setPageCount] = useState(0);
const [globalFilter, setGlobalFilter] = useState();
const [shouldShowAdditionalFilters, setShowAdditionalFilters] = useState(false);
const tableState = useTableState({ pageCount: 0, pageSize: defaultPageSize });
const [{ sortBy, filters, pageIndex, pageSize, selectedRows }] = tableState;

const isServerControlled = typeof onFetchData === "function";
const isSelectable = typeof onSelectRows === "function";
const isRowInteractive = typeof onRowClick === "function";
let data = stateData;

if (Array.isArray(simpleData)) {
data = simpleData;
}
const isSelectable = typeof onRowSelect === "function" && disableRowSelect === false;
const isRowInteractive = typeof onRowClick === "function" && disableRowClick === false;

const defaultColumn = React.useMemo(
() => ({
Expand All @@ -49,166 +39,132 @@ export default function useDataTable({
[DefaultColumnFilter]
);

const columnsWithCheckboxes = useMemo(() => {
// Process columns with some default options
const updatedColumns = columns.map((column) => ({
// Disable filtering for all columns, unless a filter is
// specified via the `Filter` prop in the column definition
disableFilters: typeof column.Filter !== "function",
...column
}));

if (isSelectable) {
const hasCheckboxColumn = Boolean(columns.find(({ id }) => id === "selection"));

if (!hasCheckboxColumn) {
return [
{
id: "selection",
cellProps: {
// Disable cell click so that clicking the checkbox doesn't also trigger the row click
isClickDisabled: true,
padding: "checkbox"
const dataTableProps = useTable(
{
columns,
data,
defaultColumn,
getRowId,
initialState: { pageIndex: 0 },
manualPagination: true,
manualFilters: true,
manualGlobalFilter: true,
pageCount: controlledPageCount,
...otherProps
},
useFilters,
useGlobalFilter,
usePagination,
useDataTableCellProps,
useRowSelect,
(hooks) => {
if (isSelectable) {
const hasCheckboxColumn = Boolean(columns.find(({ id }) => id === "selection"));

if (!hasCheckboxColumn) {
hooks.flatColumns.push((prevColumns) => [
{
id: "selection",
cellProps: {
// Disable cell click so that clicking the checkbox doesn't also trigger the row click
isClickDisabled: true,
padding: "checkbox"
},
// This column is not filterable
disableFilters: true,
// The header can use the table's getToggleAllRowsSelectedProps method
// to render a checkbox
// eslint-disable-next-line react/no-multi-comp,react/display-name,react/prop-types
Header: ({ getToggleAllRowsSelectedProps }) => (
<Checkbox {...getToggleAllRowsSelectedProps()} />
),
// The cell can use the individual row's getToggleRowSelectedProps method
// to the render a checkbox
// eslint-disable-next-line react/no-multi-comp,react/display-name,react/prop-types
Cell: ({ row }) => (
<Checkbox {...row.getToggleRowSelectedProps()} />
)
},
// tTis column is not filterable
disableFilters: true,
// The header can use the table's getToggleAllRowsSelectedProps method
// to render a checkbox
// eslint-disable-next-line react/no-multi-comp,react/display-name,react/prop-types
Header: ({ getToggleAllRowsSelectedProps }) => (
<Checkbox {...getToggleAllRowsSelectedProps()} />
),
// The cell can use the individual row's getToggleRowSelectedProps method
// to the render a checkbox
// eslint-disable-next-line react/no-multi-comp,react/display-name,react/prop-types
Cell: ({ row }) => (
<Checkbox {...row.getToggleRowSelectedProps()} />
)
},
...updatedColumns
];
...prevColumns
]);
}
}
}
);

return updatedColumns;
}, [
onSelectRows
]);
const {
state: { pageIndex, pageSize, filters, globalFilter, selectedRowIds, sortBy }
} = dataTableProps;

// Handle requests for more data
useEffect(() => {
if (isServerControlled) {
const fetch = async () => {
const { data: fetchedData, pageCount: newPageCount } = await onFetchData({
globalFilter,
data,
setData,
setPageCount,
sortBy,
filters,
pageIndex,
pageSize,
selectedRows
});

setData(fetchedData);
setPageCount(newPageCount);
};

fetch();
}
onFetchData({
globalFilter,
sortBy,
filters,
pageIndex,
pageSize
});
}, [
globalFilter,
filters,
onFetchData,
setData,
pageCount,
setPageCount,
tableState
pageIndex,
pageSize,
sortBy
]);

// Handle selection of rows
useEffect(() => {
if (isSelectable) {
onSelectRows({
data,
setData,
setPageCount,
sortBy,
filters,
pageIndex,
pageSize,
selectedRows
});
}
onRowSelect({
globalFilter,
filters,
pageIndex,
pageSize,
selectedRows: Object.keys(selectedRowIds)
});
}, [
tableState,
setData,
selectedRows,
onSelectRows
globalFilter,
filters,
onFetchData,
pageIndex,
pageSize,
selectedRowIds
]);

const handleGlobalFilterChange = useCallback((event) => {
setGlobalFilter(event.target.value);
}, [onGlobalFilterChange]);

const handleRowClick = useMemo(() => {
const onRowClickWrapper = useMemo(() => {
if (isRowInteractive) {
return (row) => () => {
onRowClick({
row,
data,
setData,
setPageCount,
sortBy,
filters,
pageIndex,
pageSize,
selectedRows
pageSize
});
};
}

return null;
}, [onRowClick]);

const dataTableProps = useTable(
{
columns: columnsWithCheckboxes,
data,
defaultColumn,
getRowID: (row, index) => `${pageIndex}.${index}`,
state: tableState,
manualFilters: isServerControlled,
manualSorting: isServerControlled,
manualPagination: isServerControlled,
pageCount,
...otherProps
},
useFilters,
usePagination,
useRowSelect,
useDataTableCellProps
);

const handleRemoveFilter = useCallback((key, multiSelectValue) => {
const filterValue = filters[key];
const onRemoveFilter = useCallback((key, multiSelectValue) => {
const filterName = filters[key].id;
const filterValue = filters[key].value;
const { setFilter } = dataTableProps;

if (Array.isArray(filterValue)) {
const newMultiFilters = filterValue.filter((valueToKeep) => valueToKeep !== multiSelectValue);
setFilter(key, newMultiFilters.length === 0 ? null : newMultiFilters);
setFilter(filterName, newMultiFilters.length === 0 ? null : newMultiFilters);
} else {
setFilter(key, null);
setFilter(filterName, null);
}
}, [filters]);

return {
...dataTableProps,
isSelectable,
setShowAdditionalFilters,
onRowClick: onRowClickWrapper,
onRemoveFilter,
shouldShowAdditionalFilters,
onGlobalFilterChange: handleGlobalFilterChange,
onRowClick: handleRowClick,
onRemoveFilter: handleRemoveFilter
setShowAdditionalFilters
};
}

0 comments on commit 5062aa8

Please sign in to comment.