From 5062aa8e58d85ad6e7d5d920570e81848576ccf9 Mon Sep 17 00:00:00 2001 From: Mike Murray Date: Thu, 16 Jan 2020 19:30:22 -0800 Subject: [PATCH] feat: update to match changes to react-table Signed-off-by: Mike Murray --- .../DataTable/helpers/useDataTable.js | 236 +++++++----------- 1 file changed, 96 insertions(+), 140 deletions(-) diff --git a/package/src/components/DataTable/helpers/useDataTable.js b/package/src/components/DataTable/helpers/useDataTable.js index 35d88046..2e54d5a3 100644 --- a/package/src/components/DataTable/helpers/useDataTable.js +++ b/package/src/components/DataTable/helpers/useDataTable.js @@ -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"; @@ -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( () => ({ @@ -49,121 +39,106 @@ 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 }) => ( + + ), + // 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 }) => ( + + ) }, - // 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 }) => ( - - ), - // 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 }) => ( - - ) - }, - ...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 }); }; } @@ -171,44 +146,25 @@ export default function useDataTable({ 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 }; }