import { Button , IconButton , Theme , Toolbar , Tooltip , createStyles , makeStyles } from '@material-ui/core' ; import AddIcon from '@material-ui/icons/Add' ; import CreateIcon from '@material-ui/icons/CreateOutlined' ; import DeleteIcon from '@material-ui/icons/DeleteOutline' ; import FilterListIcon from '@material-ui/icons/FilterList' ; import ViewColumnsIcon from '@material-ui/icons/ViewColumn' ; import classnames from 'classnames' ; import React , { MouseEvent , MouseEventHandler , PropsWithChildren , ReactElement , useCallback , useState } from 'react' ; import { TableInstance } from 'react-table' ; import { TableMouseEventHandler } from '../../types/react-table-config' ; import { ColumnHidePage } from './ColumnHidePage' ; import { FilterPage } from './FilterPage' ; export const useStyles = makeStyles ( ( theme ) => createStyles ( { toolbar : { display : 'flex' , justifyContent : 'space-between' , } , leftButtons : { } , rightButtons : { } , leftIcons : { '&:first-of-type' : { marginLeft : - 12 , } , } , rightIcons : { padding : 12 , marginTop : '-6px' , width : 48 , height : 48 , '&:last-of-type' : { marginRight : - 12 , } , } , } ) ) ; type InstanceActionButton < T extends Record < string , unknown > > = { instance : TableInstance < T > ; icon ? : JSX . Element ; onClick : TableMouseEventHandler ; enabled ? : ( instance : TableInstance < T > ) => boolean ; label : string ; variant ? : 'right' | 'left' ; } ; type ActionButton = { icon ? : JSX . Element ; onClick : MouseEventHandler ; enabled ? : boolean ; label : string ; variant ? : 'right' | 'left' ; } ; export const InstanceLabeledActionButton = < T extends Record < string , unknown > > ( { instance , icon , onClick , label , enabled = ( ) => true , } ) : ReactElement => ( < Button variant = 'contained' color = 'primary' onClick = { onClick ( instance ) } disabled = { ! enabled ( instance ) } > { icon } { label } < /Button>); export const LabeledActionButton = ( { icon , onClick , label , enabled = true } ) : ReactElement => ( < Button variant = 'contained' color = 'primary' onClick = { onClick } disabled = { ! enabled } > { icon } { label } < /Button>); export const InstanceSmallIconActionButton = < T extends Record < string , unknown > > ( { instance , icon , onClick , label , enabled = ( ) => true , variant , } ) : ReactElement => { const classes = useStyles ( { } ) ; return ( < Tooltip title = { label } aria - label = { label } > < span > < IconButton className = { classnames ( { [ classes . rightIcons ] : variant === 'right' , [ classes . leftIcons ] : variant === 'left' , } ) } onClick = { onClick ( instance ) } disabled = { ! enabled ( instance ) } > { icon } < /IconButton> < /span> < /Tooltip>); } ; export const SmallIconActionButton = ( { icon , onClick , label , enabled = true , variant , } ) : ReactElement => { const classes = useStyles ( { } ) ; return ( < Tooltip title = { label } aria - label = { label } > < span > < IconButton className = { classnames ( { [ classes . rightIcons ] : variant === 'right' , [ classes . leftIcons ] : variant === 'left' , } ) } onClick = { onClick } disabled = { ! enabled } > { icon } < /IconButton> < /span> < /Tooltip>); } ; type TableToolbarProps < T extends Record < string , unknown > > = { instance : TableInstance < T > ; onAdd ? : TableMouseEventHandler ; onDelete ? : TableMouseEventHandler ; onEdit ? : TableMouseEventHandler ; } ; export function TableToolbar < T extends Record < string , unknown > > ( { instance , onAdd , onDelete , onEdit , } ) { const { columns } = instance ; const classes = useStyles ( ) ; const [ anchorEl , setAnchorEl ] = useState < Element | undefined > ( undefined ) ; const [ columnsOpen , setColumnsOpen ] = useState ( false ) ; const [ filterOpen , setFilterOpen ] = useState ( false ) ; const hideableColumns = columns . filter ( ( column ) => ! ( column . id === '_selector' ) ) ; const handleColumnsClick = useCallback ( ( event ) => { setAnchorEl ( event . currentTarget ) ; setColumnsOpen ( true ) ; } , [ setAnchorEl , setColumnsOpen ] ) ; const handleFilterClick = useCallback ( ( event ) => { setAnchorEl ( event . currentTarget ) ; setFilterOpen ( true ) ; } , [ setAnchorEl , setFilterOpen ] ) ; const handleClose = useCallback ( ( ) => { setColumnsOpen ( false ) ; setFilterOpen ( false ) ; setAnchorEl ( undefined ) ; } , [ ] ) ; return ( < Toolbar className = { classes . toolbar } > < div className = { classes . leftButtons } > { onAdd && ( < InstanceSmallIconActionButton < T > instance = { instance } icon = { < AddIcon / > } onClick = { onAdd } label = 'Add' enabled = { ( { state } ) => ! state . selectedRowIds || Object . keys ( state . selectedRowIds ) . length === 0 } variant = 'left' / > ) } { onEdit && ( < InstanceSmallIconActionButton < T > instance = { instance } icon = { < CreateIcon / > } onClick = { onEdit } label = 'Edit' enabled = { ( { state } ) => state . selectedRowIds && Object . keys ( state . selectedRowIds ) . length === 1 } variant = 'left' / > ) } { onDelete && ( < InstanceSmallIconActionButton < T > instance = { instance } icon = { < DeleteIcon / > } onClick = { onDelete } label = 'Delete' enabled = { ( { state } ) => state . selectedRowIds && Object . keys ( state . selectedRowIds ) . length > 0 } variant = 'left' / > ) } < /div> < div className = { classes . rightButtons } > < ColumnHidePage < T > instance = { instance } onClose = { handleClose } show = { columnsOpen } anchorEl = { anchorEl } / > < FilterPage < T > instance = { instance } onClose = { handleClose } show = { filterOpen } anchorEl = { anchorEl } / > { hideableColumns . length > 1 && ( < SmallIconActionButton icon = { < ViewColumnsIcon />} onClick={handleColumnsClick} label='Show / hide columns ' variant=' right '/>)} < SmallIconActionButton icon = { < FilterListIcon / > } onClick = { handleFilterClick } label = 'Filter by columns' variant = 'right' / > < /div> < /Toolbar>); }