diff --git a/src/common/Table/Table.tsx b/src/common/Table/Table.tsx index c17860c..a9f42ba 100644 --- a/src/common/Table/Table.tsx +++ b/src/common/Table/Table.tsx @@ -26,7 +26,7 @@ export interface TableProps { orderBy: string, orderDirection: OrderDirection ) => void | Promise; - onSelect?: (rows: T[]) => void; + onSelect?: (checked: boolean, rows: T[]) => void; loading?: boolean; footerProps?: TableFooterProps; hideFooter?: boolean; @@ -84,9 +84,14 @@ function Table({ orderDirection={orderDirection} onRequestSort={onRequestSort} size={size} - onSelectAll={() => { + onSelectAll={checked => { if (onSelect) { - onSelect(data); + onSelect( + checked, + data.filter(item => + checked ? !isSelected(item) : isSelected(item) + ) + ); } }} allSelected={selected?.length === data.length} @@ -111,9 +116,9 @@ function Table({ selection={selection} columns={columns} size={size} - onSelect={row => { + onSelect={(checked, row) => { if (onSelect) { - onSelect([row]); + onSelect(checked, [row]); } }} /> diff --git a/src/common/Table/TableHead.tsx b/src/common/Table/TableHead.tsx index 5228ac5..44ee166 100644 --- a/src/common/Table/TableHead.tsx +++ b/src/common/Table/TableHead.tsx @@ -13,7 +13,7 @@ import { export interface TableHeadProps { columns: Column[]; selection: boolean; - onSelectAll?: () => void; + onSelectAll?: (checked: boolean) => void; allSelected: boolean; orderDirection: OrderDirection; orderBy: string; @@ -48,7 +48,7 @@ function TableHead({ const handleSelectAll = () => { if (onSelectAll) { - onSelectAll(); + onSelectAll(!allSelected); } }; diff --git a/src/common/Table/TableRow.tsx b/src/common/Table/TableRow.tsx index 49792fd..afbad20 100644 --- a/src/common/Table/TableRow.tsx +++ b/src/common/Table/TableRow.tsx @@ -16,7 +16,7 @@ export interface TableRowProps { selected: boolean; size?: 'small' | 'medium'; index: number; - onSelect?: (row: T) => void; + onSelect?: (checked: boolean, row: T) => void; } function EnhancedTableRow({ @@ -31,7 +31,7 @@ function EnhancedTableRow({ }: TableRowProps) { const handleSelect = () => { if (onSelect) { - onSelect(row); + onSelect(!selected, row); } }; diff --git a/src/features/UsersPage/UsersPage.tsx b/src/features/UsersPage/UsersPage.tsx index 5d11f93..ea79a83 100644 --- a/src/features/UsersPage/UsersPage.tsx +++ b/src/features/UsersPage/UsersPage.tsx @@ -1,12 +1,17 @@ import { useState } from 'react'; +import { ApolloError, useMutation } from '@apollo/client'; import { NumberParam, StringParam, useQueryParams, withDefault, } from 'use-query-params'; +import { useSnackbar } from 'material-ui-snackbar-provider'; import SortParam, { decodeSort } from 'libs/serialize-query-params/SortParam'; import useUsers from './UsersPage.useUsers'; +import { validateRowsPerPage } from 'common/Table/helpers'; +import { MUTATION_CREATE_USER, MUTATION_UPDATE_USER } from './mutations'; +import { COLUMNS, DEFAULT_SORT, DialogType } from './constants'; import { Maybe, MutationCreateUserArgs, @@ -14,17 +19,13 @@ import { User, UserInput, } from 'libs/graphql/types'; -import { validateRowsPerPage } from 'common/Table/helpers'; -import { COLUMNS, DEFAULT_SORT, DialogType } from './constants'; import { Container, IconButton, Paper } from '@material-ui/core'; import { Edit as EditIcon } from '@material-ui/icons'; import Table from 'common/Table/Table'; import TableToolbar from './components/TableToolbar/TableToolbar'; import FormDialog from './components/FormDialog/FormDialog'; -import { ApolloError, useMutation } from '@apollo/client'; -import { MUTATION_CREATE_USER, MUTATION_UPDATE_USER } from './mutations'; -import { useSnackbar } from 'material-ui-snackbar-provider'; +import { useUpdateEffect } from 'react-use'; const UsersPage = () => { const [createUserMutation] = useMutation( @@ -37,6 +38,7 @@ const UsersPage = () => { ); const [dialogType, setDialogType] = useState(DialogType.None); const [userBeingEdited, setUserBeingEdited] = useState>(null); + const [selectedUsers, setSelectedUsers] = useState([]); const snackbar = useSnackbar(); const [{ page, sort, search, ...rest }, setQueryParams] = useQueryParams({ limit: NumberParam, @@ -52,6 +54,12 @@ const UsersPage = () => { search ); + useUpdateEffect(() => { + if (selectedUsers.length > 0) { + setSelectedUsers([]); + } + }, [users]); + const handleFormDialogSubmit = async (input: UserInput) => { try { if (dialogType === DialogType.Create) { @@ -73,6 +81,16 @@ const UsersPage = () => { return false; }; + const handleSelect = (checked: boolean, items: User[]) => { + setSelectedUsers(prevState => + checked + ? [...prevState, ...items] + : prevState.filter( + item => !items.some(otherItem => otherItem.id === item.id) + ) + ); + }; + return ( @@ -90,6 +108,8 @@ const UsersPage = () => { selection columns={COLUMNS} data={users} + selected={selectedUsers} + onSelect={handleSelect} actions={[ { icon: row => {