import React from 'react' import { useStyles } from './styled'; import Table from '@material-ui/core/Table'; import TableBody from '@material-ui/core/TableBody'; import TableCell from '@material-ui/core/TableCell'; import TableContainer from '@material-ui/core/TableContainer'; import TableHead from '@material-ui/core/TableHead'; import TablePagination from '@material-ui/core/TablePagination'; import TableRow from '@material-ui/core/TableRow'; import TableSortLabel from '@material-ui/core/TableSortLabel'; import Toolbar from '@material-ui/core/Toolbar'; import Paper from '@material-ui/core/Paper'; import Checkbox from '@material-ui/core/Checkbox'; import IconButton from '@material-ui/core/IconButton'; import Tooltip from '@material-ui/core/Tooltip'; import DeleteIcon from '@material-ui/icons/Delete'; import StarRateRoundedIcon from '@material-ui/icons/StarRateRounded'; import MoreHorizIcon from '@material-ui/icons/MoreHoriz'; import { CSSProperties } from 'react'; import { useSelector } from 'react-redux'; import { activeInstance } from '../../../reducers/serviceSlice'; import { useMutation, useQuery, useQueryClient } from 'react-query'; import { ErrorInfo, MapInfo, Service } from '../../../services/Service'; import ActionChooser, { ActionType } from '../action-chooser'; import ActionDispatcher from '../action-dispatcher'; import { InputBase, Link } from '@material-ui/core'; import SearchIcon from '@material-ui/icons/Search'; import moment from 'moment' function descendingComparator(a: T, b: T, orderBy: keyof T) { if (b[orderBy] < a[orderBy]) { return -1; } if (b[orderBy] > a[orderBy]) { return 1; } return 0; } type Order = 'asc' | 'desc'; function getComparator( order: Order, orderBy: Key, ): (a: { [key in Key]: number | string | boolean | string[] | undefined }, b: { [key in Key]: number | string | string[] | boolean }) => number { return order === 'desc' ? (a, b) => descendingComparator(a, b, orderBy) : (a, b) => -descendingComparator(a, b, orderBy); } function stableSort(array: T[], comparator: (a: T, b: T) => number) { const stabilizedThis = array.map((el, index) => [el, index] as [T, number]); stabilizedThis.sort((a, b) => { const order = comparator(a[0], b[0]); if (order !== 0) return order; return a[1] - b[1]; }); return stabilizedThis.map((el) => el[0]); } interface HeadCell { id: keyof MapInfo; label?: string; numeric: boolean; style?: CSSProperties; } const headCells: HeadCell[] = [ { id: 'name', numeric: false, label: 'Name' }, { id: 'labels', numeric: false }, { id: 'creator', numeric: false, label: 'Creator', style: { width: '60px' } }, { id: 'modified', numeric: true, label: 'Modified', style: { width: '30px' } } ]; interface EnhancedTableProps { classes: ReturnType; numSelected: number; onRequestSort: (event: React.MouseEvent, property: keyof MapInfo) => void; onSelectAllClick: (event: React.ChangeEvent) => void; order: Order; orderBy: string; rowCount: number; } function EnhancedTableHead(props: EnhancedTableProps) { const { classes, onSelectAllClick, order, orderBy, numSelected, rowCount, onRequestSort } = props; const createSortHandler = (property: keyof MapInfo) => (event: React.MouseEvent) => { onRequestSort(event, property); }; return ( 0 && numSelected < rowCount} checked={rowCount > 0 && numSelected === rowCount} onChange={onSelectAllClick} size='small' inputProps={{ 'aria-label': 'select all desserts' }} /> {headCells.map((headCell) => { return ( {headCell.label} {orderBy === headCell.id ? ( {order === 'desc' ? 'sorted descending' : 'sorted ascending'} ) : null} ) })} ); } type ActionPanelState = { el: HTMLElement | undefined, mapId: number } export const MapsList = () => { const classes = useStyles(); const [order, setOrder] = React.useState('asc'); const [orderBy, setOrderBy] = React.useState('modified'); const [selected, setSelected] = React.useState([]); const [page, setPage] = React.useState(0); const [rowsPerPage, setRowsPerPage] = React.useState(5); const service: Service = useSelector(activeInstance); const { isLoading, error, data } = useQuery('maps', async () => { const result = await service.fetchAllMaps(); return result; }); const mapsInfo: MapInfo[] = data ? data : []; const [activeRowAction, setActiveRowAction] = React.useState(undefined); type ActiveDialog = { actionType: ActionType; mapId: number }; const [activeDialog, setActiveDialog] = React.useState(undefined); const handleRequestSort = (event: React.MouseEvent, property: keyof MapInfo) => { const isAsc = orderBy === property && order === 'asc'; setOrder(isAsc ? 'desc' : 'asc'); setOrderBy(property); }; const handleSelectAllClick = (event: React.ChangeEvent): void => { if (event.target.checked) { const newSelecteds = mapsInfo.map((n) => n.id); setSelected(newSelecteds); return; } setSelected([]); }; const handleRowClick = (event: React.MouseEvent, id: number): void => { const selectedIndex = selected.indexOf(id); let newSelected: number[] = []; if (selectedIndex === -1) { newSelected = newSelected.concat(selected, id); } else if (selectedIndex === 0) { newSelected = newSelected.concat(selected.slice(1)); } else if (selectedIndex === selected.length - 1) { newSelected = newSelected.concat(selected.slice(0, -1)); } else if (selectedIndex > 0) { newSelected = newSelected.concat( selected.slice(0, selectedIndex), selected.slice(selectedIndex + 1), ); } setSelected(newSelected); }; const handleChangePage = (event: unknown, newPage: number) => { setPage(newPage); }; const handleChangeRowsPerPage = (event: React.ChangeEvent) => { setRowsPerPage(parseInt(event.target.value, 10)); setPage(0); }; const handleActionClick = (mapId: number): ((event: any) => void) => { return (event: any): void => { setActiveRowAction( { mapId: mapId, el: event.currentTarget } ); event.stopPropagation(); }; }; const queryClient = useQueryClient(); const starredMultation = useMutation((id: number) => { return service.changeStarred(id); }, { onSuccess: () => { queryClient.invalidateQueries('maps'); }, onError: (error) => { // setError(error); } } ); const handleStarred = (event: React.MouseEvent, id: number) => { event.stopPropagation(); event.preventDefault(); starredMultation.mutate(id); } const handleActionMenuClose = (action: ActionType): void => { if (action) { const mapId = activeRowAction?.mapId; setActiveDialog({ actionType: action as ActionType, mapId: mapId as number }); } setActiveRowAction(undefined); }; const isSelected = (id: number) => selected.indexOf(id) !== -1; const emptyRows = rowsPerPage - Math.min(rowsPerPage, mapsInfo.length - page * rowsPerPage); return (
{selected.length > 0 ? ( ) : null}
{isLoading ? () : stableSort(mapsInfo, getComparator(order, orderBy)) .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) .map((row: MapInfo) => { const isItemSelected = isSelected(row.id); const labelId = row.id; return ( handleRowClick(event, row.id)} role="checkbox" aria-checked={isItemSelected} tabIndex={-1} key={row.id} selected={isItemSelected} style={{ border: "0" }} > handleStarred(e, row.id)}> {row.name} {row.labels} {row.creator} {moment(row.modified).fromNow()} ); })}
{/* Action Dialog */} setActiveDialog(undefined)} mapId={activeDialog ? activeDialog.mapId : -1} />
); }